Open FileStream properly for asynchronous reading/writing
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
.