如何取消 FileStream.ReadAsync( ... ) 请求?
How do I cancel a FileStream.ReadAsync( ... ) Request?
鉴于以下情况:
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace CancelAsyncFileReadFailure {
class Program {
static void Main( string[ ] args ) {
Console.WriteLine( Foo( ).Result );
Console.ReadLine( );
}
public static async Task<TaskStatus> Foo( ) {
byte[] bar = new byte[192000]; //Some arbitrarily significant number...
using ( FileStream FS = new FileSTream( @"Path/To/WarAndPeace.txt", FileMode.Open ) ){
CancellationTokenSource CTS = new CancellationTokenSource( );
Task T = FS.ReadAsync( bar, 0, 192000, CTS.Token );
CTS.Cancel( );
await T;
return T.Status;
}
}
T
将 总是 完成并且 return RanToCompletion
.
我的用例有点复杂,因为我正在从一个可以随时打开或关闭的设备中读取数据(因此不是直接从文件中读取,而是从安全的文件句柄中读取;但是在这个案例和我的实际用例中结果是相同的)。
我想打断(取消)FileStream.ReadToAsync( ).
我怎样才能停止读取它所在的位置并立即取消?
取消是尽力而为 -- 仅当操作确实能够被取消时才会发生。
这里我能想到的两种情况是它命中文件系统缓存,在这种情况下读取可以立即同步完成,或者 I/O 请求已经发送到磁盘。
好的,最好在这里回答。
您需要使用 FileOptions.Asynchronous
打开文件。如果不这样做,FileStream
将不会实现真正的取消,并且只会 return 取消 Task
如果令牌在调用 ReadAsync
.[=14 时被取消=]
Will,Cory 之前的回答实际上是对的。需要在 安全 时取消。在流读取的情况下,唯一这样的点是 before 读取实际开始。如果流读取请求在运行中被取消,当取消的任务实际完成时,您期望流的 Position
是什么?在 FileStream
的情况下将其回滚可能没问题,但是仅向前的流呢?如果您想在上一个任务转换为 Canceled 状态后立即安排另一个 ReadAsync
怎么办?你会得到一个丢失的数据块和一个可怕的损坏。从微软的角度来看,这实际上似乎是一个明智的设计。减小缓冲区大小并循环调用 ReadAsync
- 然后您将获得所需的取消语义。
鉴于以下情况:
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace CancelAsyncFileReadFailure {
class Program {
static void Main( string[ ] args ) {
Console.WriteLine( Foo( ).Result );
Console.ReadLine( );
}
public static async Task<TaskStatus> Foo( ) {
byte[] bar = new byte[192000]; //Some arbitrarily significant number...
using ( FileStream FS = new FileSTream( @"Path/To/WarAndPeace.txt", FileMode.Open ) ){
CancellationTokenSource CTS = new CancellationTokenSource( );
Task T = FS.ReadAsync( bar, 0, 192000, CTS.Token );
CTS.Cancel( );
await T;
return T.Status;
}
}
T
将 总是 完成并且 return RanToCompletion
.
我的用例有点复杂,因为我正在从一个可以随时打开或关闭的设备中读取数据(因此不是直接从文件中读取,而是从安全的文件句柄中读取;但是在这个案例和我的实际用例中结果是相同的)。
我想打断(取消)FileStream.ReadToAsync( ).
我怎样才能停止读取它所在的位置并立即取消?
取消是尽力而为 -- 仅当操作确实能够被取消时才会发生。
这里我能想到的两种情况是它命中文件系统缓存,在这种情况下读取可以立即同步完成,或者 I/O 请求已经发送到磁盘。
好的,最好在这里回答。
您需要使用 FileOptions.Asynchronous
打开文件。如果不这样做,FileStream
将不会实现真正的取消,并且只会 return 取消 Task
如果令牌在调用 ReadAsync
.[=14 时被取消=]
Will,Cory 之前的回答实际上是对的。需要在 安全 时取消。在流读取的情况下,唯一这样的点是 before 读取实际开始。如果流读取请求在运行中被取消,当取消的任务实际完成时,您期望流的 Position
是什么?在 FileStream
的情况下将其回滚可能没问题,但是仅向前的流呢?如果您想在上一个任务转换为 Canceled 状态后立即安排另一个 ReadAsync
怎么办?你会得到一个丢失的数据块和一个可怕的损坏。从微软的角度来看,这实际上似乎是一个明智的设计。减小缓冲区大小并循环调用 ReadAsync
- 然后您将获得所需的取消语义。