使用FileStream.ReadAsync()时,我应该以异步模式打开文件吗?

Mat*_*son 16 c# filestream beginread async-await

执行异步I/O的旧.Net方式FileStream是使用FileStream.BeginRead()FileStream.EndRead().

状态的MSDN文档FileStream.BeginRead():

FileStream提供两种不同的操作模式:同步I/O和异步I/O. 虽然可以使用其中任何一种,但底层操作系统资源可能仅允许以这些模式之一进行访问.

默认情况下,FileStream会同步打开操作系统句柄.在Windows中,这会降低异步方法的速度.如果使用异步方法,请使用FileStream(String,FileMode,FileAccess,FileShare,Int32,Boolean)构造函数.

.Net 4.5x对执行异步I/O的方式FileStream是使用Stream.ReadAsync().

MSDN文档FileStream.ReadAsync()直接链接到文档的链接Stream.ReadAsync().本文档未提及在异步模式下打开文件的任何需要; 实际上,文档中的示例代码显然没有这样做.

因此,我假设在使用时File.ReadAsync()不需要以异步模式打开文件.

这个假设是否正确?

[编辑]

我刚刚发现了一篇关于使用Async for File Access的MSDN文章.

这表明:

本主题中的示例使用FileStream类,该类具有导致在操作系统级别发生异步I/O的选项.通过使用此选项,您可以避免在许多情况下阻止ThreadPool线程.

要启用此选项,请在构造函数调用中指定useAsync = true或options = FileOptions.Asynchronous参数.

所以,现在我在想,我应该可以打开该文件在异步模式......如果是这样,这是有点遗憾的是,在文档中提供的示例代码ReadAsync()不能打开该文件异步!

Sri*_*vel 17

在win32中,您需要指定FILE_FLAG_OVERLAPPED以使用异步文件IO.在.net世界中,您使用isAsync参数FileStream来实现相同的目标.如果您不这样做,操作将不是异步的.

遗憾的是FileStream.ReadAsync,它的相关方法未能记录它.

您可以通过窥视实现来确认这一点.

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;
}
Run Code Online (Sandbox Code Playgroud)

base.ReadAsync最终将Stream.Read同步调用方法,ThreadPool给人的印象是操作是异步的,但实际上并非如此.

相关信息来自Windows上的并发编程一书(Pg:818):

与此同时CreateFile,您必须在创建时指定您希望使用FileStream进行异步执行.有了 FileStream,你可以通过将true作为isAsync参数传递给构造函数重载来接受它.流的IsAsync 属性随后将返回true.如果你没有通过这个值,调用BeginReadBeginWrite会成功的.但是他们将使用Stream的基类实现,它不提供真正的异步文件I/O的好处.

以上信息是关于APM方法(因为这是旧书)但仍然是相关的.