У меня есть следующий безобидный фрагмент кода:
using (var sw = new StreamWriter(path))
{
await sw.WriteAsync(msg.BodyText);
}
Это асинхронная задача, выполняющаяся в фоновом потоке службы Windows.Задача, по сути, представляет собой насос сообщений, который читает из очереди сообщений и записывает сообщения на диск.Это единственная строка кода, которая записывает в файловую систему.
Существует ряд таких задач прокачки сообщений.Они инициализируются следующим образом:
_tasks = _config.MessagePumps.Select((pump) =>
{
return Task.Factory.StartNew(() =>
StartMessagePump(pump, _source.Token), TaskCreationOptions.LongRunning);
}).ToArray();
Я знаю, что StreamWriter использует буферизацию во время операций записи из соображений производительности и что его оборачивание в блок using обеспечивает сброс буфера при удалении StreamWriter.Задача, которая вызывает этот код, поддерживает отмену между обработкой а-ля
while(!token.IsCancellationRequested)
{
var msg = await GetNextMessage();
await SaveMessage(msg);
}
Когда служба остановлена, обработчик события OnStop
вызывает CancellationTokenSource.Cancel()
, а затем Task.WaitAll()
длясинхронно ожидайте завершения всех фоновых задач следующим образом:
protected override void OnStop()
{
_source.Cancel();
Task.WaitAll(_tasks);
}
Проблема заключается в том, что при проверке записанных файлов после остановки службы все файлы, которые активно записывались во время инициализации остановки,неполный.Есть ли что-то очевидное, что я упускаю из виду?Можете ли вы предложить какие-либо советы по устранению неполадок?