У меня есть набор задач, которые получают строки, которые я пытаюсь координировать в поток. Все выглядит хорошо, но на практике я получаю
Поток в данный момент используется предыдущей операцией в потоке
после Task.WhenAll
звонка.
Пример:
private readonly List<Task<string>> _objectData = new List<Task<string>>();
private readonly SemaphoreSlim _writerSemaphore = new SemaphoreSlim(1, 1);
private async Task SafelyWrite(StreamWriter streamWriter, string field)
{
await _writerSemaphore.WaitAsync();
if (field.IsNullOrWhiteSpace())
{
return;
}
streamWriter.Write(field);
await streamWriter.FlushAsync();
_writerSemaphore.Release();
}
public override async Task Build(StreamWriter streamWriter)
{
streamWriter.Write('{');
await Task.WhenAll(
_objectData.Select(async str => SafelyWrite(streamWriter, await str)));
// await Task.Delay(10);
// If I don't wait for a few milliseconds the app
// will throw an error on this line that the stream
// is currently being written to?
streamWriter.Write('}');
await streamWriter
.FlushAsync();
}
С задержкой или без нее, если я посмотрю содержимое потока, все это действительно. Все закончилось, просто StreamWriter
думает, что нет? Если я подожду несколько миллисекунд, StreamWriter
думает, что все закончилось, и я могу написать закрывающий блок.
Есть ли что-то между Task.WhenAll
и SemaphoreSlim
, которого мне не хватает?
(Извините за объем кода, казалось, что минимальный сбой, но полезный пример завершен)