Coffeehouse Post

Single Post Permalink

View Thread: Asynchrony, Progress Reporting and Cancellation
  • User profile image

    What's really missing in this discussion are asynchronous operations from I/O. These may occur within the "UI thread" event queue (keyboard and mouse input) or via I/O completion ports. These types of asynchronous operations are what I was mostly referring to. It's a lot "lighter" to use one of the new Task based asynchronous I/O operations to, for instance, download data from a web service than it is to use a BackgroundTask and synchronous I/O operations. It's unfortunate that WebClient.DownloadStringTaskAsync and friends don't have overloads for handling progress and cancellation (can't imagine why this was left out, actually), but it is possible to roll your own extension methods for this. In fact, there's a Code Project article that does this with the CTP. The result uses I/O completion ports rather than background threads to achieve the asynchronous I/O operation and includes progress (and you could easily add cancellation) support.

    Oh, and I'm fully aware that BackgroundWorker operates using the thread pool. This still means it's using a background thread, it's just a pooled thread. This removes the overhead of having to create the thread every time, but it doesn't remove the overhead involved with context switching and scheduling of the thread. So the "premise" isn't "false". The remarks on the number of threads used by the thread pool are also way off the mark as the scheduling is far more complicated than just "the number of background workers you have running at the same time." Further, there's very little difference in how Task<T> and BackgroundWorker schedule work on the thread pool (at least in the typical scenario, since scheduling is something configurable for Task<T>). BackgroundWorker is no more or less suited for small or medium size work than Task<T> is.

    The recommendation for when to use Thread is fairly accurate, but the example with TcpListener isn't, really. Rather than use a dedicated thread there, you'd be better off with I/O completion ports again, using one of the async operations. There's little use for a BackgroundWorker in a server scenario, so for everything else you could rely on either more I/O completion ports and/or Tasks. Also, just FYI, there is no Future<T>. Future<T> became Task<T> in beta 1 of .NET 4.0.