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

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

FileStream.BeginRead()的MSDN文档指出:

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

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

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

FileStream.ReadAsync()的MSDN文档直接链接到Stream.ReadAsync()的文档。 本文档未提及是否需要以异步模式打开文件; 实际上,文档中的示例代码显然不会这样做。

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

这个假设是否正确?

[编辑]

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

这表明:

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

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

所以现在我认为我应该以异步模式打开文件…如果是这样,有点不幸的是, ReadAsync()文档中提供的示例代码不会异步打开文件!

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

很遗憾, FileStream.ReadAsync及其相关方法无法记录它。

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

 public override Task 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最终将在ThreadPool同步调用Stream.Read方法,给人的印象是操作是异步的,但实际上并非如此。

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

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

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