Подтвердить что ты не робот

Много процессов обрабатывают и записывают один файл

У меня есть txt файл ABC.txt, который будет прочитан и написан несколькими процессами. Поэтому, когда один процесс читает или записывает файл ABC.txt, файл ABC.txt должен быть заблокирован, чтобы другие процессы не могли читать или писать на него. Я знаю, что перечисление System.IO.FileShare может быть правильным способом справиться с этой проблемой. Но я использовал другой способ, который я не уверен, правильно ли это. Следующее - мое решение.

Я добавил в папку еще один файл Lock.txt. Прежде чем я смогу прочитать или записать в файл ABC.txt, я должен иметь возможность читать из файла Lock.txt. И после того, как я прочитал или написал файл ABC.txt, я должен освободить эту возможность. Ниже приведен код.

        #region Enter the lock
        FileStream lockFileStream = null;
        bool lockEntered = false;
        while (lockEntered == false)
        {
            try
            {
                lockFileStream = File.Open("Lock.txt", FileMode.Open, FileAccess.Read, FileShare.None);
                lockEntered = true;
            }
            catch (Exception)
            {
                Thread.Sleep(500);
            }
        }
        #endregion

        #region Do the work
        // Read from or write to File ABC.txt
        // Read from or write to other files
        #endregion

        #region Release the lock
        try
        {
            if (lockFileStream != null)
            {
                lockFileStream.Dispose();
            }
        }
        catch
        {
        }
        #endregion

На моем компьютере кажется, что это решение работает хорошо, но я все еще не могу убедиться, что он подходит.

Изменить: Много процессов, а не несколько потоков в одном процессе.

4b9b3361

Ответ 1

С# с именем EventWaitHandle - это путь сюда. Создайте экземпляр дескриптора ожидания в каждом процессе, который хочет использовать этот файл, и дайте ему имя, которое разделяется всеми этими процессами.

EventWaitHandle waitHandle = new EventWaitHandle(true, EventResetMode.AutoReset, "SHARED_BY_ALL_PROCESSES");

Затем при доступе к файлу подождите waitHandle и по завершении обработки файла установите его так, чтобы следующий процесс в очереди мог получить к нему доступ.

waitHandle.WaitOne();
/* process file*/
waitHandle.Set();

Когда вы называете дескриптор ожидания события, это имя является общим для всех процессов в операционной системе. Поэтому, чтобы избежать возможности столкновений, используйте руководство для имени ( "SHARED_BY_ALL_PROCESSES" выше).

Ответ 2

Мьютекс в С# может использоваться для нескольких процессов. Вот пример для нескольких процессов, записывающих один файл:

using (var mutex = new Mutex(false, "Strand www.jakemdrew.com"))
{
    mutex.WaitOne();
    File.AppendAllText(outputFilePath,theFileText);
    mutex.ReleaseMutex();
}

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

Дополнительное чтение здесь:

http://www.albahari.com/threading/part2.aspx#_Mutex

Ответ 3

Ваше решение подвержено ошибкам. Вы в основном реализовали блокировку с двойной проверкой (http://en.wikipedia.org/wiki/Double-checked_locking), которая может быть очень опасной.

Лучшим решением было бы либо установить изоляцию потоков, когда только один поток когда-либо обращается к файлу и делает это, читая из очереди, по которой запросы на чтение или запись помещаются другими потоками (и, конечно, очередь защищена путем взаимного эксклюзивного доступа по потокам), или когда потоки синхронизируются либо с помощью устройств синхронизации (lock разделы, так и без каких-либо изменений), либо с помощью какой-либо другой логики доступа к файлу (например, System.IO.FileShare). )

Ответ 4

С# имеет встроенный lock, и вы можете использовать его, создав статический объект, доступный для всех потоков:

private static object lockObject {get;set;}

public static object LockObject {get{return lockObject ?? lockObject = new object();}}


void YourMethod()
{
   lock(LockObject)  // all other threads will wait for y
   {
      using(var lockFileStream = File.Open("Lock.txt", FileMode.Open, FileAccess.Read, FileShare.None))
      {
         //Do what you need with the file.  
      }

   }
}

Это создает подход Thread Threading к вашей проблеме.

Ответ 5

Если бы это был я, я бы установил что-то вроде SQL Server Compact Edition для чтения/записи этих данных.

Однако, если вы хотите иметь возможность блокировать доступ к ресурсу, который используется несколькими процессами, вам необходимо использовать Mutex или семафор.

Класс Mutex - это .Net-оболочка вокруг механизма блокировки уровня ОС.

Обзор примитивов синхронизации