Asynchronous memory streaming approach: which of the following?
The fact is that MemoryStream
's Read/WriteAsync
methods don't actually provide any kind of true asynchronous implementation. All they do is perform the operation synchronously and return an already completed Task
. Therefore there is no benefit to calling the async methods when you know it's a MemoryStream
. In fact, it's just completely unnecessary overhead.
Now, forgetting that for a second just to answer your question on style, the first approach is better one because you don't allocate/schedule a new Task
unnecessarily (e.g. with Task::Run
), but I don't know why you wouldn't just use a using()
statement in that approach. So here's the cleanest/simplest IMHO:
private async static Task WriteToStreamFirstVariantSimplified()
{
using(MemoryStream memoryStream = new MemoryStream())
{
byte[] data = new byte[256];
try
{
await memoryStream.WriteAsync(data, 0, data.Length);
}
catch(Exception exception)
{
//Handling exception
}
}
}
Ilya Tereschuk
Updated on June 08, 2022Comments
-
Ilya Tereschuk almost 2 years
I am working on solution which uses asynchronous memory streaming and I am thinking about right approach for implementing such. Which one is more convenient? The first, simple:
//First approach: linear async private async static Task WriteToStreamFirstVariant() { MemoryStream memoryStream = new MemoryStream(); byte[] data = new byte[256]; try { await memoryStream.WriteAsync(data, 0, data.Length); } catch(Exception exception) { //Handling exception } finally { memoryStream.Dispose(); } }
Or the second with nested tasks and closures?
//Second approach: nested tasks async private async static Task WriteToStreamSecondVariant() { await Task.Run(async () => { byte[] data = new byte[256]; using (MemoryStream memoryStream = new MemoryStream()) { await memoryStream.WriteAsync(data, 0, data.Length) .ContinueWith((Task writingTask) => { //Handling exceptions AggregateException exceptions = writingTask.Exception; }); } }); }
-
usr over 10 yearsJust don't use async here. The code snippet in this answer shows a bad practice. I worry that someone might copy it and use it.
-
Drew Marsh over 10 yearsI totally agree, but people should hopefully be reading the explanation first. In the end, I just wanted to provide the best way to write the code from an async perspective, but you absolutely shouldn't waste your cycles (or the CPU's) writing it this way for MemoryStream.
-
David L. Sargent almost 8 yearsAlso note that MicroSofts version of MemoryStream.CoptyToAsync is there for a reason. If you are trying to to MemoryStream.CopyTo in an Async method it will fail under heavy load sometimes. Switching to CopyToAsync fixed this for us.
-
FreakyAli over 4 years@DavidL.Sargent Been trying to use the
CopyToAsync
method for so long now it never works!! the resulting stream is always empty