Search code examples
c#asynchronousasync-awaitfilestreamcancellationtokensource

How do I cancel a FileStream.ReadAsync( ... ) Request?


Given the following :

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 will always finish and return RanToCompletion.

My use case is somewhat more complex in that I am reading from a device which may be opened or closed at any time (and as such am not reading directly from a file, but from a safe file handle; however the results are the same in both this case and my actual use case).

I want to interrupt (cancel) FileStream.ReadToAsync( ).

How can I go about doing that in such a way that it will stop reading where it is at and cancel right away?


Solution

  • Alright, better answer here.

    You need to open the file with FileOptions.Asynchronous. If you don't, FileStream will not implement true cancellation and will only return a cancelled Task if the token was cancelled at the time of calling ReadAsync.