使用 FileStream.ReadAsync() 时,我应该以异步模式打开文件
本文关键字:异步 模式 文件 我应该 ReadAsync FileStream 使用 | 更新日期: 2023-09-27 18:33:36
FileStream
执行异步 I/O 的旧 .Net 方法是使用 FileStream.BeginRead()
和 FileStream.EndRead()
。
FileStream.BeginRead()
的 MSDN 文档指出:
FileStream 提供两种不同的操作模式:同步 I/O 和异步 I/O。虽然可以使用这两种模式,但基础操作系统资源可能只允许以其中一种模式进行访问。
默认情况下,文件流同步打开操作系统句柄。在 Windows 中,这会减慢异步方法的速度。如果使用异步方法,请使用 FileStream(String、FileMode、FileAccess、FileShare、Int32、Boolean(构造函数。
为FileStream
执行异步 I/O .Net 4.5x
方法是使用 Stream.ReadAsync()
。
FileStream.ReadAsync()
的 MSDN 文档直接链接到 Stream.ReadAsync()
的文档。本文档未提及以异步模式打开文件的任何需要;实际上,文档中的示例代码显然没有这样做。
因此,我假设使用 File.ReadAsync()
时无需以异步模式打开文件。
这个假设正确吗?
[编辑]
我刚刚发现了一篇关于使用异步进行文件访问的 MSDN 文章。
这说明:
本主题中的示例使用 FileStream 类,该类具有导致在操作系统级别发生异步 I/O 的选项。通过使用此选项,在许多情况下可以避免阻塞线程池线程。
若要启用此选项,请在构造函数调用中指定 useAsync=true 或 options=FileOptions.Asynchronous 参数。
所以现在我想我应该以异步模式打开文件......如果是这样,很遗憾,ReadAsync()
文档中提供的示例代码不会异步打开文件!
在 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;
}
base.ReadAsync
最终将在ThreadPool
中同步调用Stream.Read
方法,给人的印象是操作是异步的,但实际上并非如此。
相关信息来自 Windows 上的并发编程一书 (Pg:818(:
与
CreateFile
一样,您必须在创建时指定 喜欢使用FileStream进行异步执行。跟FileStream
,您可以通过将 true 作为isAsync
参数传递给 构造函数重载,它接受它。溪流的IsAsync
属性随后将返回 true。如果您未能通过此 值,对BeginRead
和BeginWrite
的调用将成功。但他们 将使用 Stream 中的基类实现,它提供 真正的异步文件 I/O 没有任何好处。
以上信息是关于APM方法的(因为这是一本旧书(,但仍然相关。