Создайте StreamReader / FileStream в одно и то же время двумя экземплярами, выдает исключение. Файл используется другим процессом. - PullRequest
0 голосов
/ 13 января 2019

Я читаю текстовый файл в сетевой папке, основываясь на событиях FileWatcher. У меня есть два экземпляра одной и той же программы, читающей файл, когда экземпляры 1 и 2 читают файл в те же самые секунды и миллисекунды, я получаю исключение, говорящее о том, что файл используется другим процессом. Если между экземплярами 1 и 2 существует разница в несколько миллисекунд, эта ошибка блокировки не появляется.

Вещи, которые я пробовал 1. Попытался использовать параметр FileShare.ReadWrite, но проблема по-прежнему возникает.

  1. Пытался сделать некоторую задержку между экземплярами 1 и 2, но иногда возникает проблема.

  2. Пытался использовать оператор using для закрытия объектов FileStream, но проблема по-прежнему возникает.

Любые мысли / предложения, чтобы избежать этой проблемы.

Фрагменты кода

StreamReader sr = null;
FileStream fs = null;
try 
{
    fs = new FileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.Read);
    sr = new StreamReader(fs);
    while (sr.Peek() != -1)
    {
     // Does only read operations no write.
    }
    sr.Close();
    fs.Close();
}
catch (Exception Ex)
{
    try
    {
        if (sr != null)
            sr.Close();
        if (fs != null)
            fs.Close();
    }
    catch (Exception innerException)
    {

    }  
 }

Ответы [ 2 ]

0 голосов
/ 13 января 2019

Одной из идей было бы использовать какую-то стратегию повторов и заключить код в try/catch. Вы также можете поместить свои объявления fs и sr в операторы using, чтобы вам не пришлось беспокоиться о вызове Close для них:

int retries = 3;

while (retries > 0)
{
    try
    {
        using (var fs = File.OpenRead(FileName))
        using (var sr = new StreamReader(fs))
        {
            while (sr.Peek() != -1)
            {
                // Does only read operations no write.
            }
        }

        break; // Exit the while loop if successful
    }
    catch
    {
        // Decrement our retry count and wait a bit if we're not done
        if (--retries > 0) Thread.Sleep(TimeSpan.FromSeconds(5));
    }
}
0 голосов
/ 13 января 2019

Надеюсь, кто-то может дать вам более четкий ответ, но если чтение файла критично, тогда я, вероятно, просто выброслю его в блок try / catch и подожду несколько миллисекунд, если он не удастся из-за блокировки, прежде чем пытаться снова .

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

...