TaskCompletionSource - Trying to understand threadless async work

asynchronous, task-parallel-library

Solution

`TaskCompletionSource` is used to create `Task` objects that don't execute code.

They're used quite a bit by Microsoft's new async APIs - any time there's I/O-based asynchronous operations (or other non-CPU-based asynchronous operations, like a timeout). Also, any `async Task` method you write will use TCS to complete its returned `Task`.

I have a blog post Creating Tasks that discusses different ways to create `Task` instances. It's written from an `async`/`await` perspective (not a TPL perspective), but it still applies here.

Also see Stephen Toub's excellent posts:

- The Nature of TaskCompletionSource

- Mechanisms for Creating Tasks

- await anything; (using `TaskCompletionSource` to `await` anything).

- Using Tasks to implement the APM Pattern (creating `Begin`/`End` using `TaskCompletionSource`).

Problem

I'm trying to understand the purpose of `TaskCompletionSource` and its relation to async/threadless work. I think I have the general idea but I want to make sure my understanding is correct. I first started looking into the Task Parallel Library (TPL) to figure out if there was a good way to create your own threadless/async work (say you're trying to improve scalability of your ASP.NET site) plus understanding of the TPL looks like it will be very important in the future (`async`/`await`). Which led me to the `TaskCompletionSource`. From my understanding it looks like adding `TaskCompletionSource` to a one of your classes doesn't really do much in as making your coding async; if you're still executing sync code then the call to your code will block. I think this is even true of microsoft APIs. For example, say in `DownloadStringTaskAsync` off of `WebClient` class, any setup / sync code they are doing initially will block. The code you're executing has to run on some thread, either the current thread or you will have to spin off a new one. So you use `TaskCompletionSource` in your own code when you're calling other `async` calls from Microsoft so the client of your classes doesn't have to create a new thread for your class to not block. Not sure how Microsoft does their async APIs internally. For example, there is a new `async` method off of the `SqlDataReader` for .Net 4.5. I know there is IO Completion Ports. I think it's a lower level abstraction (C++?) that probably most C# developers won't use. Not sure if IO completion Ports will work for Database or network calls (HTTP) or if its just used for file IO. So the question is, am I correct in my understanding correct? Are there certain things I've represented incorrectly?

Original source