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
标志:(