I have a snippet of code that is writing to a memory stream in an asynchronous way (.NET Standard 2.1)
- Create a list of hot tasks, one per a line
- Then await when all of them will be finished
- Flush the writer buffer to the memoryStream at the end
Code:
await using var memoryStream = new MemoryStream();
await using var writer = new StreamWriter(memoryStream);
var recordTasks = stringRecordsToWrite.Select(r => writer.WriteLineAsync(r));
await Task.WhenAll(recordTasks);
await writer.FlushAsync();
var result = memoryStream.ToArray();
Questions
There are a couple of questions that bothering me:
- There were reports that time to time some records had been skipped. Thus, I wonder, could such implementation be the root cause. I've tried to reproduce the issue locally, but, unfortunately, no success
- Also Resharper highlights that 'writer' (within SELECT statement) is a captured variable and disposed in outer scope. Can it be a problem?
Or those are false traces, and the implementation is fine, and I should try to found the reason out in other place
CodePudding user response:
You have a single stream. It doesn't really make sense to write to it asynchronously in parallel - any number of things could go wrong. I don't even know what MemoryStream
's thread safety is like, and I can't see any documentation about that. The documentation for StreamWriter
explicitly states:
By default, a StreamWriter is not thread safe. See TextWriter.Synchronized for a thread-safe wrapper.
I would strongly advise you to just iterate sequentially, e.g.
foreach (var item in stringRecordsToWrite)
{
await writer.WriteLineAsync(item);
}