none
async/await with other threads/pools RRS feed

  • Question

  • I've been reading about async/await in our prep to move to DevStudio 2012.  I get most of what I've read however I haven't seen a good explanation about how to take advantage of this compiler "sugar" when you aren't using the the automatic .NET thread pool.

    Our software uses custom background threads and other thread pools (such as SmartThreadPool) because often we are performing what can be expensive background tasks, monitoring external processes, crawling a filesystem, etc.  All of these are candidates to stay away from the the .NET thread pool as we'd hate to have it interfere with .NET remoting, etc.

    Based on what I've read it looks like one would need to wrap things in a TaskCompletionSource object or create your own implementation of GetAwaiter and INotifyCompletion.  Is this the correct path to take when you *only* want to deviate from the examples in what threads are used to back the task?  I find it odd that there isn't a simpler way to create a task that doesn't draw its thread from the .NET thread pool.

    Thanks for any light you can shed on this.

    Monday, April 8, 2013 6:47 PM

Answers

  • If you build a custom task scheduler that uses your "custom thread pool", you can use that to create the Task or Task<T>, and use await on that.  I wouldn't make my own awaiter - just use a normal Task (either via TaskCompletionSource or the scheduler).

    The default TaskScheduler (what you get when you use Task.Run, etc) will use the .NET ThreadPool.

    That being said, I'd revisit using the default thread pool.  The threadpool in .NET 4, and again in .NET 4.5, has gotten some huge improvements.  You might find that it outperforms the other options (such as "SmartThreadPool") that were advantageous in CLR 2...


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".


    Monday, April 8, 2013 6:57 PM
    Moderator

All replies

  • That's a great question and one I've never thought about.  I'm not an ASYNC expert nor a TASK expert but all I've read has touted the non-processor affinty model.  So how that would tie in with customized thread pools I don't know.  However, in neither the Async or Task suuport have I seen any attributes or creation options which allow one to direct work to a specific thread pool.


    JP Cowboy Coders Unite!

    Monday, April 8, 2013 6:54 PM
  • If you build a custom task scheduler that uses your "custom thread pool", you can use that to create the Task or Task<T>, and use await on that.  I wouldn't make my own awaiter - just use a normal Task (either via TaskCompletionSource or the scheduler).

    The default TaskScheduler (what you get when you use Task.Run, etc) will use the .NET ThreadPool.

    That being said, I'd revisit using the default thread pool.  The threadpool in .NET 4, and again in .NET 4.5, has gotten some huge improvements.  You might find that it outperforms the other options (such as "SmartThreadPool") that were advantageous in CLR 2...


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".


    Monday, April 8, 2013 6:57 PM
    Moderator
  • Using just `await` there is nothing inherently associated with the thread pool.  The current `SynchronizationContext` is what is used to determine how continuations are run.  If none is present, then the default behavior is to use the default synchronization context, which uses the thread pool.  If you don't want that to happen then simply be sure that some other synchronization context is set.  It is also an option, as you said, to use a custom awaiter which schedules a continuation in a particular manor.

    Keep in mind that the async/await functionality isn't creating the tasks that do the real work, it's just utilizing existing tasks to configure the continuations of those tasks (the continuations themselves generally shouldn't be doing much work).  Now in lots of common examples one will use `Task.Run` to start a task to do CPU bound units of work (which can then be awaited on) but you would simply use your own mechanism for creating a task if you don't want to use the thread pool.

    Monday, April 8, 2013 7:05 PM
  • Thanks for the info Reed, we can look into the TaskScheduler!  That was the glue I seemed to be missing.

    As far as the managed threadpool goes is the info here still accurate with regards to the bit about "When not to use Thread Pool Threads"?   Our server processes certainly fit the mold of some of those and we additionally use .NET remoting which I believe also draws upon the managed thread pool.  We would like to keep our server threading model from interfereing with clients trying to connect to our server processes (which is why we avoid the manged pool).  If something significant has changed in regard to thread priority, long-running/blocking threads, etc we'd consider the built-in pool of course.

    Monday, April 8, 2013 7:06 PM
  • As far as the managed threadpool goes is the info here still accurate with regards to the bit about "When not to use Thread Pool Threads"?   Our server processes certainly fit the mold of some of those and we additionally use .NET remoting which I believe also draws upon the managed thread pool.  We would like to keep our server threading model from interfereing with clients trying to connect to our server processes (which is why we avoid the manged pool).  If something significant has changed in regard to thread priority, long-running/blocking threads, etc we'd consider the built-in pool of course.

    That is still valid advice (it's .NET 4.5 still), but it's not always true in every scenario -

    For example, the max threads is more of an issue in 32bit scenarios, but in 64bit processes, the thread pool allows a lot of threads by default, and grows fairly quickly - so it's not always an issue in practical terms.

    The STA issue is still valid, as is foreground threads, etc.


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    Monday, April 8, 2013 8:02 PM
    Moderator