Если я использую WriteAsync, у меня все еще будут проблемы, когда несколько специалистов по фону пытаются записать в один и тот же файл .txt? - PullRequest
0 голосов
/ 13 марта 2019

У меня есть несколько backgroundworkers, которые все хотят записать в log.txt, что приводит к исключению The process cannot access the file 'C:\...\log.txt' because it is being used by another process..Я знаю, что это длинный выстрел, но поможет ли это, если я использую WriteAsync() вместо этого или это не даст никакого эффекта?

(Если это не простое решение, думаю, мне нужно реализовать объект mutex, который я видел раньше.)

public static void WriteToLog(string text, bool append = true)
{
    try
    {
        using (var writer = new StreamWriter("log.txt", append))
        {
            writer.Write(text);
            // writer.WriteAsync(text); // Would this 'queue up' instead of trying 
                                           to access the same process at the same time?
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine($"ERROR! Fejl i loggen! {ex.Message}. {ex.StackTrace}");
    }
}

Ответы [ 3 ]

1 голос
/ 13 марта 2019

Хотя использование каркаса ведения журнала является лучшим решением, для конкретного решения проблемы ...

В режиме добавления требуется, чтобы файл был заблокирован, а когда блокировка не можетполучить вы получите ошибку, которую вы получаете.Вы можете синхронизировать все потоки, но тогда вы на время заблокируете их.Использование WriteAsync не устраняет проблему.

Лучшее решение - поставить в очередь ваши сообщения, а затем назначить выделенный поток для их удаления и записи в журнал.Таким образом, вам не требуется синхронизация , потому что все записи выполняются одним потоком.

Снова предупреждаю: используйте каркас журналирования.

1 голос
/ 13 марта 2019

На самом деле ответить на ваш вопрос. Нет, это не спасет вас от проблемы блокировки. async - это не волшебное ключевое слово, которое синхронизирует все потоки. Наоборот, он может даже запустить свой собственный поток в зависимости от синхронизатора.

Если вы не используете модель с одним потоком, тогда да, это будет стоять в очереди, так как синхронизатор имеет только один поток для работы. Затем он должен поставить в очередь все асинхронные вызовы с переключением контекста. Однако, если вы используете однопоточную модель, у вас не возникнет этой проблемы.

1 голос
/ 13 марта 2019

Вы можете решить проблему несколькими способами.

  1. Используйте механизм блокировки для синхронизации доступа к общему ресурсу. Один хороший вариант для этого сценария ReaderWriterLockSlim

  2. Используйте каркас журналирования (есть много хороших библиотек и очень надежных).

Лично я предпочел бы перейти с каркасом ведения логов, поскольку есть много полезных функций, которые вы будете использовать (приложение для работы с файлами, db logger и т. Д.), Которые предложат вам чистое решение для ведения журналов с нулевыми взломами и обслуживанием.

...