#c#
#c#
Вопрос:
У меня есть длительно выполняющаяся фоновая задача, которая представляет собой просто цикл while, постоянно повторяющий a BlockingCollection
для записи сообщений в файл. Сначала я использовал foreach
цикл, который создавал streamwriter
и записывал строку асинхронно.
public static BlockingCollection<LogMessage> LogMessages = new BlockingCollection<LogMessage>();
private static async void RunTask()
{
while (true)
{
var allMessages = LogMessages.GetConsumingEnumerable();
foreach (var message in allMessages)
{
using (StreamWriter sr = new StreamWriter(File.Open(DebugPath, FileMode.Append)))
{
await sr.WriteLineAsync(message.Text);
}
}
}
}
Приведенный выше код работал хорошо, но мне показалось, что это не лучший способ использовать streamwriter
, поэтому я попытался переключить инструкции foreach
and using
. Это привело к созданию файла отладки, но файл оставался размером 0 КБ и никогда не сохранялся. Также я не смог открыть файл, потому что он использовался, пока приложение было открыто.
using (StreamWriter sr = new StreamWriter(File.Open(DebugPath, FileMode.Append)))
{
foreach (var message in allMessages)
{
// I suspect it's not waiting for this to finish.
await sr.WriteLineAsync(message.Text);
}
}
Это ожидаемое поведение фоновой задачи? Каков правильный способ сделать это?
Комментарии:
1. Я бы просто использовал append или написал весь текст.
2. Также я бы попытался создавать новые файлы время от времени…. например, укажите Year_Month_Day_Hour в имени файла … таким образом, каждый час появляется новый файл … или что-то в этом роде.
3. Возможно, вам потребуется очистить via StreamWriter. Сброс . Хотя, я согласен, что append, вероятно, является лучшим подходом, если вы хотите видеть журнал во время его выполнения.
4. @JonathanAlfaro Я просто изменил его, чтобы удалить foreach и streamwriter, теперь это просто
File.AppendAllLines(DebugPath, debugMessages);
. Происходит тот же результат, я открыл файл в VSCode, и он сказал мне, что файл занят или заблокирован.5. Для исходного кода вам нужно вызвать перегрузку,
File.Open()
которая принимаетFileShare
параметр, чтобы вы могли указать, что другие процессы / дескрипторы могут читать и / или записывать файл, пока он у вас открыт.
Ответ №1:
Вы можете запустить отдельную задачу для синхронной записи сообщений в файл:
public async void RunTask()
{
await DoTask();
}
public Task DoTask()
{
return Task.Run(() =>
{
using (StreamWriter sr = new StreamWriter(File.Open(DebugPath, FileMode.Append)))
{
foreach (var message in allMessages)
{
sr.WriteLine(message);
}
}
});
}
Комментарии:
1. Зачем мы это делаем? Иногда (ну, постоянно) лучше всего объяснить ваш взгляд на проблему и как это может помочь