Реализация остановки и перезапуска при передаче файлового потока - как? C# .NET
Я ищу тексты или советы по осуществлению остановки и перезапуска при передаче файлового потока.
Цель состоит в том, чтобы приложение использовало один источник чтения и выводило данные на несколько источников записи, а также могло перезапускаться с записанной позиции в случае сбоя передачи.
Приложение пишется на C# .NET.
Код Псуэдо:
while (reader.Read())
{
foreach(writer in writers)
{
writer.WriteToStream();
}
}
Я должен быть в состоянии осуществить остановку или паузу. Который мог бы работать так. Чтобы остановить, продолжить помечается как ложное:
while (reader.Read() && Continue)
{
foreach(writer in writers)
{
writer.WriteToStream();
}
}
Очевидно, что на этом этапе мне нужно записать количество прочитанных байтов и количество байтов, записанных в каждый источник записи.
Мои вопросы:
Если бы я записывал только прочитанные байты и использовал это для перезапуска, один или несколько авторов могли бы написать, а другие нет. Простой перезапуск с использованием показателя прогресса чтения может повредить записанные данные. Поэтому мне нужно использовать запись "записано байт на записывающее устройство" в качестве моей новой стартовой позиции. Как я могу быть уверен, что байты были записаны (у меня может не быть возможности прочитать файл из источника записи для чтения длины файла)?
Может кто-нибудь посоветовать или указать мне правильное направление текста по этому вопросу?
1 ответ
Используйте событие синхронизации потока.
(Псевдокод):
ManualResetEvent _canReadEvent = new ManualResetEvent(true);
public void WriterThreadFunc()
{
while (_canReadEvent.Wait() && reader.Read())
{
foreach(writer in writers)
{
writer.WriteToStream();
}
}
}
public void Pause()
{
_canReadEvent.Reset();
}
public void Continue()
{
_canReadEvent.Set();
}
Хорошая вещь состоит в том, что поток записи не будет потреблять никакого ЦП, когда он приостановлен, и он будет продолжать напрямую сигнализировать (в отличие от использования флага и Thread.Sleep()
)
Другое замечание: любая проверка должна быть первым аргументом в while
поскольку reader.Read()
в противном случае будет считываться из потока (но содержимое будет игнорироваться, так как флаг будет препятствовать выполнению блока while).