Tip 2: Distinguish CPU-Bound work from IO-bound work

Sign in to queue

The Discussion

  • User profile image
    srini datla

    I wish I saw this video earlier. I was using TPL for IO bound work which lead to thread starvation. Nice video.

  • User profile image

    @Srini, we also saw this within Visual Studio itself. We wanted to write the new features of the product using async. But they still had to speak to the older synchronous components within VS. The result was that a lot of our async methods had to make blocking calls to those components.

    Result: thread starvation, because we were using all available threads, and the TPL was only giving us one additional thread a second.


    Fix: to fix this we've been systematically spreading the "async virus" throughout those components, making them all use async from top to bottom, so that we don't starve the threadpool.

  • User profile image

    Interesting video, but can you just clarify something? When he keeps mentioning the "thread pool", does that include threads that you kick off yourself by creating a new instance of System.Threading.Thread and then calling the Start method? I was always under the impression that threads created like that are nothing to do with the thread pool but perhaps I'm wrong and it just grabs a free thread from the thread pool anyway. At the moment if I want to run a load of tasks that need to wait for I/O then I would do a loop and create a new System.Threading.Thread instance for each iteration and start it - telling each of these threads to execute my method that starts the I/O request. So am I going to get any performance benefit out of using Await or would it already be starting each I/O request at the same time as it is?


  • User profile image

    Enjoyed the video ... you say not to use TPL for IO bound work which I understand mostly ... but if I'm awaiting Async framework methods that do IO bound work, are they internally using the threadpool for their work?

    I guess I have a hard time comparing to my current pattern of starting a task with Task.Factory(() => downloadfile())...

    downloadfile() that takes a while and at the end calls Dispatcher.Invoke() to finish up on the UI thread.

    Clearly the syntax is much better with async/await and I'm all for it ... is that the only difference?

    Thanks a lot!

  • User profile image

    I think I know the answer to my question now thanks to some of your other videos ...

    I guess a lot of the framework async methods (like those on HttpClient for instance) don't do their work on threadpool threads per-se... or at least they don't block them ... it looks like the "IOCP" (IO completion thread) is what is always running that queues our code for continuation in the HttpClient case...

    So yes I see now that using the built-in Async methods should be much faster than using the threadpool and blocking on synchronous methods myself.

    I would assume most if not all of the framework provided async methods are similar to the HttpClient example in that they do not block a threadpool thread while running? This would be in line with the general guidance to NOT make an async method available if all it's going to do is block on a threadpool thread, since the framework users can do that as they desire... I'm sure the .net framework class designers follows that guideline (or if not have some other good reason)

    Thanks again for all your great videos that explain these things ... I feel like async/await is dramatically changing the way I code for the better!

  • User profile image

    Great discussion here, Lucian.  Thanks!  I first did multi-threaded apps in assembly language back in the 80's (DOS), so I understand threading concepts. But I need to catch up on some of these new framework constructs.

  • User profile image

    Great video, thanks! Now I know when to use Task.Run method and when not to using async/await. But I am wondering how do I create a custom asynchronous IO-Bound method like GetStringAsync (HttpClient class), ExecuteNonQueryAsync (SqlCommand class) and others? I don't know better way than "return Task.Run(() => SomeSynchronousMethod());". Can someone provide an example how to create such a method without Task.Run?

Add Your 2 Cents