Entries:
Comments:
Posts:

Loading User Information from Channel 9

Something went wrong getting user information from Channel 9

Latest Achievement:

Loading User Information from MSDN

Something went wrong getting user information from MSDN

Visual Studio Achievements

Latest Achievement:

Loading Visual Studio Achievements

Something went wrong getting the Visual Studio Achievements

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

Download

Right click “Save as…”

Async Tip #2: It's crucial to distinguish CPU-bound work (should be done on threadpool) from IO-bound work (which needn't).

You can download slides for this talk from Lucian's blog.
 
I remember reading an old Android dev blog post. It said: "1. A good practice in creating responsive applications is to make sure your main UI thread does the minimum amount of work. 2. Any potentially long task that may hang your application should be handled in a different thread. 3. Typical examples of such tasks are network operations, which involve unpredictable delays."
 
There's a serious flaw in this logic... When your program is just sitting there twiddling its thumbs, waiting for a network packet to come back, it's not doing any work, and so doesn't need to go on a background thread. You should await it instead!
 
Await opens up a whole new simpler world of programming. You can mostly get by without any background threads at all. That means all of your code can run on the UI thread, which makes it much  easier to do databinding, to update the UI, and so on.
 
Await also improves responsiveness of servers. That's because the threadpool takes some time to ramp up. If you use await, then you can ramp up instantly.
 
So when do you need to use the threadpool, and how? Answer: only when you've got some CPU-bound work, like a compute-bound iteration over a large dataset; and do it using Parallel.ForEach or Task.Run.
 
 

Tags:

Follow the Discussion

  • srini datlasrini datla

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

  • @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.

  • Chris128Chris128

    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?

    Thanks
    Chris

  • travistravis

    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!

  • travistravis

    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!

  • 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.

Remove this comment

Remove this thread

close

Comments Closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums,
or Contact Us and let us know.