I've been attempting to implement a Stream
that supports ReadAsync
and WriteAsync
, and given the spareseness of the documentation, I'm struggling to understand how to do so properly. Specifically, with respect to the stream's cursor position. A similar question was asked here and here regarding the old BeginRead
function. The documentation for that function seemed to indicate that BeginRead
should not be called again until any pending asynchronous operations had completed.
Given that BeginRead
is now deprecated no longer recommended for new development and Stream
has likely been significantly altered to implement the new Async functions, things are once again unclear. (EDIT: Usually this kind of warning means that the new functions are implemented directly and the old functions call the new ones and are only still there for backwards compatibility, but that appears to not quite be the case here).
The ReadAsync
and WriteAsync
functions are defined such that they don't take the desired read/write stream position as their Win32 counterparts do (a very poor design choice in my opinion), but instead rely on the current position held by the stream implementation. That situation is fine if one of two conditions hold:
ReadAsync
and WriteAsync
must grab the current cursor position for use by the operation and update it as if the operation completed (or not update it at all) before they return the Task
, orReadAsync
or WriteAsync
can be made until all previous async calls have been completed.Outside of those two conditions, the caller can never be sure of the position the read or write will occur at because pending asynchronous operations could alter the position of the stream in between any Seek
and call to ReadAsync
or WriteAsync
. Neither of these conditions is documented as a requirement, so I'm left to wonder how it's supposed to function.
My whitebox testing seems to indicate that at least for the FileStream
version of Stream
, the stream position updates asynchronously, which would seem to indicate that the second condition (only one pending operation allowed) is still the one that is required, but that seems like a serious limitation (it certainly precludes any kind of internal scatter-gather implementation).
Can anyone provide any kind of authoritative information as to whether the old BeginRead
limitation still applies to ReadAsync
or not?
Can anyone provide any kind of authoritative information as to whether the old
BeginRead
limitation still applies toReadAsync
or not?
The same limitations apply for BeginRead
and ReadAsync
.
The old APM methods haven't been deprecated. They are still fully supported and there's nothing wrong with using them. However, the async
methods are considerably easier to use so the documentation suggests using them instead.
All these async
"overloads" on these old classes usually do still consist of calling BeginXXX
and EndXXX
or at most both options call a shared method (e.g. FileStream.BeginReadAsync
). I have never seen any code (in the framework or otherwise) that has APM wrapper methods over the async
one.
Therefore, calling ReadAsync
will result in calling BeginRead
so any limitation applies to both. Furthermore, since Stream
isn't thread-safe and doesn't advertise as being concurrent-safe (which is slightly different) it's safe to assume you can't flood it with async
requests concurrently.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With