Everything a Task
In Chapter 7 you discovered how the async and await keywords simplify the composing and consuming of Task-based asynchronous logic. Also, in Chapter 3 we mentioned that a Task represents a piece of asynchronous activity. This asynchronous activity could be compute but could as easily be I/O. An example of a noncompute Task is when you turned an IAsyncResult into a Task utilizing Task.Factory.FromAsyncResult. If you could literally represent anything as a Task, then you could have more areas of your code that could take advantage of the async and await keywords. In this chapter you will discover there is a very simple API to achieve just this. Taking advantage of this API, we will show you a series of common use cases, from an efficient version of WhenAny to stubbing out Task-based APIs for the purpose of unit testing.