tabs ↹ over ␣ ␣ ␣ spaces

by Jiří {x2} Činčura

Open FileStream properly for asynchronous reading/writing

3 Aug 2017 .NET, Multithreading/Parallelism/Asynchronous/Concurrency

Asynchronous stuff with async/await in C# is great. But as with any other great tool, there are some gotchas that might cost you something (performance, memory, etc.). Today I’m going to talk about FileStream.

With .NET 4.5 the FileStream has also the XxxAsync methods. Thus, one might expect when using these that everything works as good as it could be. Well, not exactly. From outside perspective, it will probably work just fine - the calling thread is not blocked. But it’s not as good as it could be.

On Windows, when you want to open/create a HANDLE (which the file ultimately is) and use overlapped operations (which is just a different name for asynchronous operations in Windows operating system), you need to specify “asynchronous” flag. On FileStream that’s the FileOptions.Asynchronous (or the isAsync bool parameter) in constructor. As you can guess, this does matter for await.

Let’s take a look at ReadAsync for example. The method will end up here. In case the flag was not present it will “fallback” to base.ReadAsync, which in turn will eventually call regular Read in Task (and hence on thread pool thread). In case the FileOptions.Asynchronous was present the overlapped operations will be used. In the ReadAsync’s case here via this. And the real overlapped operations are a different ball game. System handles that. Way more efficient.

Hence next time, if you’re looking for every possible performance improvement, don’t forget to specify FileOptions.Asynchronous.