Сбой доступа к файлу с помощью streamreader, поскольку он используется другим процессом

#c# #.net #streamreader

#c# #.net #потоковый читатель

Вопрос:

У меня есть приложение .NET Core, которое является многопоточным. Одним из аспектов приложения является проверка работоспособности, которая анализирует файл журнала на наличие ошибок. Это код, используемый для доступа к нему:

 using StreamReader reader = new StreamReader(GetLogFile);
 

Я заметил, что иногда получаю эту ошибку:

2021-01-12 11:15:14.890ОШИБКА Z APP = 2227 COMP = 3789 [16] Проверка работоспособности Проверка журналов на наличие проблем с приложением выдала необработанное исключение после 96.2407ms — Logger = Microsoft.Расширения.Диагностика.Проверка работоспособности.DefaultHealthCheckService,Level=ОШИБКА,ThreadId = 16,,Исключение =»System.IO.IOException: процесс не может получить доступ к файлу ‘c:appsCb.PublisherLogsCb.Publisher .log’, потому что он используется другим процессом.

Я изменил свой код на это:

 using StreamReader reader = new StreamReader(File.OpenRead(GetLogFile));
 

При тестировании я не сталкивался с проблемой, но она возникала так редко, что я не уверен на 100%, что она решена. Может ли мое изменение решить эту проблему или есть лучший способ сделать это?

Дополнительная информация

Это вся функция:

 private int LogLine(Regex reg)
{
    GetLogFile = DefaultLogFile.GetLogFileName();
    using StreamReader reader = new StreamReader(File.OpenRead(GetLogFile));
    string line;
    int lineNo = 0;
    int errorLine = 0;
    while ((line = reader.ReadLine()) != null)
    {
        Match match = reg.Match(line);
        if (match.Success)
        {
            errorLine = lineNumber;
        }
        lineNo  ;
    }
    return errorLine;
}
 

Если я установлю точку останова в while строке в Visual Studio и запущу функцию, а затем попытаюсь отредактировать файл в Блокноте, у меня не получится с ошибкой The process cannot access the file because it is being used by another process .

После некоторого расследования мне интересно, действительно ли эта строка может быть причиной моих проблем:

 var fileTarget = (FileTarget)LogManager.Configuration.FindTargetByName("file-target");
 

Это в DefaultLogFile.GetLogFileName :

 public string GetLogFileName()
{
    var fileTarget = (FileTarget)LogManager.Configuration.FindTargetByName("file-target");
    var logEventInfo = new LogEventInfo();
    string fileName = fileTarget.FileName.Render(logEventInfo);
    if (!File.Exists(fileName))
    {
        throw new Exception("Log file does not exist.");
    }
    return fileName;
} 
 

Комментарии:

1. Является ли это приложение многопоточным? Возможно, краткое описание других технологий (например, WPF, ASP.NET Ядро и т.д.) в приложении помогло бы.

2. ОК. Я добавил немного больше информации. Это . Приложение Net core и является многопоточным.

3. В этом случае вполне возможно, что это может быть проблемой, когда несколько потоков пытаются получить доступ к этому файлу. У вас есть блокировка вокруг кода доступа к файлу? Считывают ли несколько потоков из этого файла? Случайный / случайный характер ошибки, которую вы описываете, типичен для проблемы с потоками. Я думаю, было бы неплохо опубликовать остальные функции, из которых считывается этот файл.

Ответ №1:

Предложенного вами решения, вероятно, будет достаточно, да:

 using StreamReader reader = new StreamReader(File.OpenRead(GetLogFile));
 

Однако правильным решением для вас является проверка того, что файл не блокируется из любого другого места, где вы используете файл. Это также означает, что ваша система ведения журнала (будь то Log4Net, NLog, Serilog и т. Д.) Должна быть правильно настроена, Чтобы не использовать эксклюзивную блокировку файла журнала. Я считаю, что фреймворки ведения журнала обычно не блокируют его от доступа для чтения по умолчанию, поэтому, если вы не настроили конфигурацию, фреймворк ведения журнала не должен быть проблемой.