Задача: записывать в файл данные из нескольких потоков.
При последовательной записи (режим Append
) работает без ошибок.
_waitWriteHandler.WaitOne();
using (BinaryWriter bw = new BinaryWriter(new FileStream(Destination, FileMode.Append, FileAccess.Write, FileShare.Write)))
{
bw.Write(data);
}
_waitWriteHandler.Set();
А если сначала создать файл:
using (BinaryWriter bw = new BinaryWriter(new FileStream(Destination, FileMode.Create, FileAccess.Write, FileShare.None)))
{
bw.Write(new byte[destinationFileSize]);
}
И в разные места начать писать данные:
_waitWriteHandler.WaitOne();
using (BinaryWriter bw = new BinaryWriter(new FileStream(Destination, FileMode.Open, FileAccess.Write, FileShare.None)))
{
bw.BaseStream.Position = position;
bw.Write(data);
}
_waitWriteHandler.Set();
то выдает необработанное исключение, что файл уже используется другим процессом (причем дает часть данных записать, всегда по-разному).
Использую класс Thread
и AutoResetEvent
для синхронизации.
Можно получать эксклюзивные права на запись в файл(FileShare.None
), как вы и делаете, но постоянные переоткрытия файла с блокировкой будут очень узким местом.
Также придётся отлавливать System.IO.IOException
, например, в бесконечном цикле, чтобы дождаться освобождения файла.
Лучше всего собирать данные в разных потоках, но писать в одном, специально для этого выделенном, через механизм очереди.
Скармливаете ему "задачи", а он их выполняет. (Это называется producer-consumer
)
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Как можно получить имя папки "Мой компьютер" для windows 10
есть шифрование на c# и требуется сделать аналогичное на androidПробовал по разному вот к чему пришел: на c#
Как можно проще реализовать ImapClient(GemBoxEmail