фоновая задача, не ожидающая записи в файл

#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. Зачем мы это делаем? Иногда (ну, постоянно) лучше всего объяснить ваш взгляд на проблему и как это может помочь