使用 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()文档中提供的示例代码不会异步打开文件!

使用 FileStream.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。如果您未能通过此 值,对BeginReadBeginWrite的调用将成功。但他们 将使用 Stream 中的基类实现,它提供 真正的异步文件 I/O 没有任何好处。

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