TAP: Await anything (not only Tasks)

The async/await pattern is simple yet effective way to work with tasks. Its ingeniousity is that the programmer is focused on implementation of the function at the first place, leaving the technical details to the compiler which does some behind-the-scenes magic to make sure that async methods can:

  • run asynchronously,
  • capture or disregard the context (via ConfigureAwait(bool))
  • use all benefits of TAP (Task-based Asynchronous Pattern)

A nice touch of the async/await syntax is that it is easy to convert any synchronous method into its asynchronous counterpart, without sacrificing code clarity or increasing its complexity.

Interestingly enough, the await keyword is not really limited to Tasks, and as a matter of fact it can be used for any object for which it makes sense to wait for. This blog post is devoted to defining a class which can be awaited with await keyword, and yet is by no mean a Task at all!

So what is the compiler doing and how to make sure it understands our custom awaiting desire? In order to demonstrate, let’s try the following code which uses a plain AutoResetEvent. One thing to notice is that – instead of WaitOne() in line 21 – we try to await it by adding the await keyword before.
Continue reading “TAP: Await anything (not only Tasks)”