C# 使用FileStream.ReadAsync()时,是否应以异步模式打开文件?

C# 使用FileStream.ReadAsync()时,是否应以异步模式打开文件?,c#,async-await,filestream,beginread,C#,Async Await,Filestream,Beginread,对于FileStream执行异步I/O的旧.Net方法是使用和 FileStream.BeginRead()的MSDN文档说明: FileStream提供两种不同的操作模式:同步I/O和异步I/O。虽然可以使用这两种模式中的任何一种,但底层操作系统资源可能只允许以其中一种模式进行访问 默认情况下,FileStream同步打开操作系统句柄。在Windows中,这会减慢异步方法的速度如果使用异步方法,请使用FileStream(字符串、文件模式、文件访问、文件共享、Int32、布尔)构造函数。 为文

对于
FileStream
执行异步I/O的旧.Net方法是使用和

FileStream.BeginRead()的MSDN文档说明:

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

默认情况下,FileStream同步打开操作系统句柄。在Windows中,这会减慢异步方法的速度如果使用异步方法,请使用FileStream(字符串、文件模式、文件访问、文件共享、Int32、布尔)构造函数。

文件流执行异步I/O的
.Net 4.5x
方法是使用

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

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

这个假设正确吗

[编辑]

我刚刚发现

该条规定:

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

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


所以现在我想我应该在异步模式下打开文件。。。如果是这样,那么有点遗憾的是,
ReadAsync()
文档中提供的示例代码没有异步打开文件

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

遗憾的是,
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;
}
public override Task ReadAsync(字节[]缓冲区、整数偏移量、整数计数、取消令牌取消令牌)
{
...
如果(!this._isAsync | |!Environment.IsWindowsVistaOrAbove)
{
返回base.ReadAsync(缓冲区、偏移量、计数、取消令牌);
}
...
返回状态对象;
}
base.ReadAsync
最终将在
ThreadPool
中同步调用
Stream.Read
方法,给人的印象是操作是异步的,但实际上不是

书中的相关信息(第818页):

CreateFile
一样,必须在创建时指定 希望使用文件流进行异步执行。具有
FileStream
,通过将true作为
isAsync
参数传递给 构造函数重载,它接受它。流的
IsAsync
属性随后将返回true。如果你没有通过这个考试 值,则调用
BeginRead
BeginWrite
将成功。但他们 将使用Stream中的基类实现,它提供 真正的异步文件I/O没有任何好处


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

了解这一点非常重要!似乎有许多网页讨论了
ReadAsync()
,但没有提到这一非常重要的事实(例如,)是的,您链接的网站是一个非常好的网站,但遗憾的是,它没有谈到这一点。我看到那个链接说,对于async,我们只使用单线程,并显示了流读取器的示例。这是错误的,因为实现碰巧使用了
ThreadPool
,而没有
isAsync
标志:(