In win32, you need to specify FILE_FLAG_OVERLAPPED to make use of asynchronous File IO. In .net world you use isAsync
parameter of FileStream
to achieve the same. If you fail to do so, operations will not be asynchronous.
It is a shame that FileStream.ReadAsync
and its related methods failed to document it.
You can confirm this by peeking into the implementation.
public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
...
if (!this._isAsync || !Environment.IsWindowsVistaOrAbove)
{
return base.ReadAsync(buffer, offset, count, cancellationToken);
}
...
return stateObject;
}
base.ReadAsync
will eventually call to Stream.Read
method synchronously in ThreadPool
giving the impression that operation is async, but really not.
Related information from Concurrent Programming On Windows book (Pg:818):
As with CreateFile
, you must specify at creation time that you'd
like to use a FileStream for asynchronous execution. With
FileStream
, you do this by passing true as the isAsync
argument to
the constructor overloads, which accept it. The stream's IsAsync
property will subsequently return true. If you fail to pass this
value, calls to BeginRead
and BeginWrite
will succeed. But they
will use the base class implementation from Stream, which provides
none of the benefits of true asynchronous file I/O.
Above information is about APM methods(as this is old book) but still relevant one.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…