Страницы

Поиск по вопросам

четверг, 11 апреля 2019 г.

c# блокировка файлов

В php есть возможность одновременного доступа к файлу с блокировками на запись LOCK_EX (экслюзивный доступ для записи) и на чтение LOCK_SH (общий доступ для чтения) Блокировка вызывается после открытия файла через flock
При вызове блокировки поведение зависит от типа блокировки. В общем то оно работает аналогично ReaderWriterLock и в c# для подобного поведения нужно использовать его. Однако ReaderWriterLock в c# работает в рамках одного процесса (и не относится непосредственно к файлам).
Более того windows будет мешать одновременному доступу к файлу с разных процессов.
В c# есть FileShare, но похоже, что это всего лишь разрешение другому процессу открывать файл на такой же тип доступа (из msdn не сильно понятно что но на самом деле)
Приведите пример как в c# сделать такое же поведение блокировки с общим файлом, как в php или его абстрактном аналоге ReaderWriterLock
upd: вижу требуется пояснение какое именно поведение ожидается допустим есть несколько процессов которые почти одновременно хотят
читать читать читать писать читать писать
Первые 3 получат разрешение на одновременное чтение. 4й подождет и получит блок для записи когда первые 3 отпустят файл. 5й будет ждать пока 4й не освободит, а 6й пока не освободит 5й
Так вот варианты FileShare.ReadWrite или FileShare.Write никакой очереди не соблюдают (я проверил 2х писателей и у меня на выходе в файле каша). Они всего лишь указывают, что другой процесс может делать без выброса исключения. Но никак не защищают файлы от одновременной записи.
Если же поставить эксклюзивную блокировку без FileShare, то другие процессы будут получать исключения, что мы и хотим избежать
upd2: и снова никто не понимает в чем проблема.
Проблема: много процессов, которые могут читать и писать в файл.
Цель: защитить общий файл от конкурентного доступа, дабы в один момент только один писатель мог писать. Не "запретить другим доступ",а обеспечить конкурирующий доступ, когда много читателей может много читать одновременно, но писать только один, то есть то, для чего нужен ReaderWriterLock (не вижу я принципиальной разницы между ним и системой блокировки файлов в php)
Вариант "лови исключения и повторяй через 100мс до победного" не выдерживают критики. Писатель, который ждет пока файл освободится, может никогда не дождаться, потому что в эти 100мс куча читателей могут открыть файл для себя. Правильное решение - блокировка для чтения/записи ставится в очередь и в пхп (и не только в нем) это доступно из коробки,но в c# я не нашел как это делается.
Если сказать коротко, то вопрос звучит так: как сделать ReaderWriterLock для файлов, которые шарятся между несколькими процессами?


Ответ

Разобрался в чате, чего же от меня хотелось.
С помощью пары FileAccess/FileShare нужного поведения не добиться. Требуемое поведение в WInAPI доступно через LockFileEx, использование в C# можно увидеть тут: https://stackoverflow.com/questions/1784195/using-lockfileex-in-c-sharp

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

Отправить комментарий