MSDN Magazine - January 2009 - (Page 116) .NET MaTTErs STePhen Toub Round-Robin Access To The ThreadPool Q I’m currently using the Microsoft .NET Framework ThreadPool, and I’ve run into a situation I’m not sure how to solve. I start off with a large batch of work items that get queued, and then a second (smaller batch) arrives after the first batch starts its processing. Initially, some of the work in the large batch will be dispatched to all of the worker threads in the ThreadPool. However, when the second batch arrives, I want the distribution to be fair, with each batch getting serviced equally, rather than the first batch getting full attention due to it arriving first. When one of the batches finishes, I’d like whichever one still needs processing to then get the attention of all the worker threads. Is there anything I can do to layer such batching functionality on top of the ThreadPool? In past columns, I’ve showed how to layer various types of functionality on top of the existing .NET ThreadPool. In the October 2004 issue of MSDN Magazine, I showed how to add support onto the ThreadPool for waiting on queued work items (see msdn.microsoft.com/magazine/cc163914). In the November 2004 issue, I showed how to add support for work item priorities (see msdn.microsoft.com/ magazine/cc163896). And in the March 2006 issue, I showed how to add cancellation support (see msdn.microsoft.com/magazine/cc163644). In the future, I’ll be able to look back at the January 2009 issue and say that there I showed how to add round-robin scheduling support on top of the ThreadPool. The problem you’re looking to solve first requires an understanding of how the ThreadPool dispatches work. Internally, it maintains a queue of the work items that have been queued to it. When a thread in the pool is available to execute work, it goes back to the work queue and pulls off the next item. The order in which this processing happens is undocumented and should most definitely not be relied upon (as it could and likely will change in future versions). Today it’s implemented in a very simple manner: a first-in-firstout (FIFO) queue. Thus, the first work to be queued will be the first work to be picked up by a thread. In your batching scenario, this means all of the work from the first batch will be in the queue in front of all of the work from the second batch. And thus all of Send your questions and comments for Stephen to netqa@microsoft.com. 116 msdn magazine A the first batch’s work will be dispatched before that of the second batch. For some scenarios, this is fine and optimal. For your scenario, you need more control. One of the easiest ways to get that control from the ThreadPool is to substitute your own delegate for the one the user really wants executed. As an example, let’s say you wanted to catch all unhandled exceptions thrown out of queued work and raise an event for each. To do that, you could write code such as that in Figure 1. Then, instead of using ThreadPool.QueueUserWorkItem, you’d use ExceptionThreadPool.QueueUserWorkItem. The work would still be executed by the ThreadPool, but the pool’s threads would actually be executing the delegate you queued rather than the one the user provided. Invoking your delegate would then invoke the user-provided delegate, catching any exceptions and raising the target event. Note that this technique, while powerful, does come at a cost: an extra delegate needs to be allocated, an extra delegate needs to be invoked, and so forth. Whether that cost is prohibitive can be determined only by you and your scenarios, but this kind of layering is typically more cost-effective than writing your own thread pool from scratch. This is, of course, a very simple example, but you can do more complicated things. The priority pool example to which I referred earlier stores the user-provided delegates in its own data structures. It then queues to the pool a substitute delegate that comes back and searches those data structures for the right delegate to execute, preferring to execute first those that have higher priorities. You can employ a similar technique to address your batching predicament. Figure 1 Shimming the ThreadPool public static class ExceptionThreadPool { public static void QueueUserWorkItem( WaitCallback callback, object state) { ThreadPool.QueueUserWorkItem(delegate { try { callback(state); } catch (Exception exc) { var handler = UnhandledException; if (handler != null) handler(null, new UnhandledExceptionEventArgs(exc, false)); } }); } public static event UnhandledExceptionEventHandler UnhandledException; } http://msdn.microsoft.com/magazine/cc163914 http://msdn.microsoft.com/magazine/cc163914 http://msdn.microsoft.com/magazine/cc163896 http://msdn.microsoft.com/magazine/cc163896 http://msdn.microsoft.com/magazine/cc163644
Table of Contents Feed for the Digital Edition of MSDN Magazine - January 2009 Toolbox CLR Inside Out Basic Instincts Cutting Edge Test Run First Look Geneva Framework Silverlight Windows Mobile Service Station Security Briefs Extreme ASP.NET Foundations .NET Matters { End Bracket } MSDN Magazine - January 2009 MSDN Magazine - January 2009 - (Page Intro) MSDN Magazine - January 2009 - (Page Cover1) MSDN Magazine - January 2009 - (Page Cover2) MSDN Magazine - January 2009 - (Page 1) MSDN Magazine - January 2009 - (Page 2) MSDN Magazine - January 2009 - (Page 3) MSDN Magazine - January 2009 - (Page 4) MSDN Magazine - January 2009 - (Page 5) MSDN Magazine - January 2009 - (Page 6) MSDN Magazine - January 2009 - (Page 7) MSDN Magazine - January 2009 - (Page 8) MSDN Magazine - January 2009 - Toolbox (Page 9) MSDN Magazine - January 2009 - Toolbox (Page 10) MSDN Magazine - January 2009 - Toolbox (Page 11) MSDN Magazine - January 2009 - Toolbox (Page 12) MSDN Magazine - January 2009 - Toolbox (Page 13) MSDN Magazine - January 2009 - Toolbox (Page 14) MSDN Magazine - January 2009 - CLR Inside Out (Page 15) MSDN Magazine - January 2009 - CLR Inside Out (Page 16) MSDN Magazine - January 2009 - CLR Inside Out (Page 17) MSDN Magazine - January 2009 - CLR Inside Out (Page 18) MSDN Magazine - January 2009 - CLR Inside Out (Page 19) MSDN Magazine - January 2009 - CLR Inside Out (Page 20) MSDN Magazine - January 2009 - Basic Instincts (Page 21) MSDN Magazine - January 2009 - Basic Instincts (Page 22) MSDN Magazine - January 2009 - Basic Instincts (Page 23) MSDN Magazine - January 2009 - Basic Instincts (Page 24) MSDN Magazine - January 2009 - Basic Instincts (Page 25) MSDN Magazine - January 2009 - Basic Instincts (Page 26) MSDN Magazine - January 2009 - Basic Instincts (Page 27) MSDN Magazine - January 2009 - Basic Instincts (Page 28) MSDN Magazine - January 2009 - Basic Instincts (Page 29) MSDN Magazine - January 2009 - Basic Instincts (Page 30) MSDN Magazine - January 2009 - Cutting Edge (Page 31) MSDN Magazine - January 2009 - Cutting Edge (Page 32) MSDN Magazine - January 2009 - Cutting Edge (Page 33) MSDN Magazine - January 2009 - Cutting Edge (Page 34) MSDN Magazine - January 2009 - Cutting Edge (Page 35) MSDN Magazine - January 2009 - Cutting Edge (Page 36) MSDN Magazine - January 2009 - Cutting Edge (Page 37) MSDN Magazine - January 2009 - Cutting Edge (Page 38) MSDN Magazine - January 2009 - Test Run (Page 39) MSDN Magazine - January 2009 - Test Run (Page 40) MSDN Magazine - January 2009 - Test Run (Page 41) MSDN Magazine - January 2009 - Test Run (Page 42) MSDN Magazine - January 2009 - Test Run (Page 43) MSDN Magazine - January 2009 - Test Run (Page 44) MSDN Magazine - January 2009 - Test Run (Page 45) MSDN Magazine - January 2009 - Test Run (Page 46) MSDN Magazine - January 2009 - Test Run (Page 47) MSDN Magazine - January 2009 - Test Run (Page 48) MSDN Magazine - January 2009 - Test Run (Page 49) MSDN Magazine - January 2009 - First Look (Page 50) MSDN Magazine - January 2009 - First Look (Page 51) MSDN Magazine - January 2009 - First Look (Page 52) MSDN Magazine - January 2009 - First Look (Page 53) MSDN Magazine - January 2009 - First Look (Page 54) MSDN Magazine - January 2009 - First Look (Page 55) MSDN Magazine - January 2009 - First Look (Page 56) MSDN Magazine - January 2009 - First Look (Page 57) MSDN Magazine - January 2009 - First Look (Page 58) MSDN Magazine - January 2009 - First Look (Page 59) MSDN Magazine - January 2009 - First Look (Page 60) MSDN Magazine - January 2009 - First Look (Page 61) MSDN Magazine - January 2009 - First Look (Page 62) MSDN Magazine - January 2009 - First Look (Page 63) MSDN Magazine - January 2009 - Geneva Framework (Page 64) MSDN Magazine - January 2009 - Geneva Framework (Page 65) MSDN Magazine - January 2009 - Geneva Framework (Page 66) MSDN Magazine - January 2009 - Geneva Framework (Page 67) MSDN Magazine - January 2009 - Geneva Framework (Page 68) MSDN Magazine - January 2009 - Geneva Framework (Page 69) MSDN Magazine - January 2009 - Geneva Framework (Page 70) MSDN Magazine - January 2009 - Geneva Framework (Page 71) MSDN Magazine - January 2009 - Geneva Framework (Page 72) MSDN Magazine - January 2009 - Geneva Framework (Page 73) MSDN Magazine - January 2009 - Geneva Framework (Page 74) MSDN Magazine - January 2009 - Silverlight (Page 75) MSDN Magazine - January 2009 - Silverlight (Page 76) MSDN Magazine - January 2009 - Silverlight (Page 77) MSDN Magazine - January 2009 - Silverlight (Page 78) MSDN Magazine - January 2009 - Silverlight (Page 79) MSDN Magazine - January 2009 - Silverlight (Page 80) MSDN Magazine - January 2009 - Silverlight (Page 81) MSDN Magazine - January 2009 - Silverlight (Page 82) MSDN Magazine - January 2009 - Silverlight (Page 83) MSDN Magazine - January 2009 - Silverlight (Page 84) MSDN Magazine - January 2009 - Silverlight (Page 85) MSDN Magazine - January 2009 - Silverlight (Page 86) MSDN Magazine - January 2009 - Silverlight (Page 87) MSDN Magazine - January 2009 - Windows Mobile (Page 88) MSDN Magazine - January 2009 - Windows Mobile (Page 89) MSDN Magazine - January 2009 - Windows Mobile (Page 90) MSDN Magazine - January 2009 - Windows Mobile (Page 91) MSDN Magazine - January 2009 - Windows Mobile (Page 92) MSDN Magazine - January 2009 - Service Station (Page 93) MSDN Magazine - January 2009 - Service Station (Page 94) MSDN Magazine - January 2009 - Service Station (Page 95) MSDN Magazine - January 2009 - Service Station (Page 96) MSDN Magazine - January 2009 - Service Station (Page 97) MSDN Magazine - January 2009 - Service Station (Page 98) MSDN Magazine - January 2009 - Security Briefs (Page 99) MSDN Magazine - January 2009 - Security Briefs (Page 100) MSDN Magazine - January 2009 - Security Briefs (Page 101) MSDN Magazine - January 2009 - Security Briefs (Page 102) MSDN Magazine - January 2009 - Extreme ASP.NET (Page 103) MSDN Magazine - January 2009 - Extreme ASP.NET (Page 104) MSDN Magazine - January 2009 - Extreme ASP.NET (Page 105) MSDN Magazine - January 2009 - Extreme ASP.NET (Page 106) MSDN Magazine - January 2009 - Extreme ASP.NET (Page 107) MSDN Magazine - January 2009 - Extreme ASP.NET (Page 108) MSDN Magazine - January 2009 - Foundations (Page 109) MSDN Magazine - January 2009 - Foundations (Page 110) MSDN Magazine - January 2009 - Foundations (Page 111) MSDN Magazine - January 2009 - Foundations (Page 112) MSDN Magazine - January 2009 - Foundations (Page 113) MSDN Magazine - January 2009 - Foundations (Page 114) MSDN Magazine - January 2009 - Foundations (Page 115) MSDN Magazine - January 2009 - .NET Matters (Page 116) MSDN Magazine - January 2009 - .NET Matters (Page 117) MSDN Magazine - January 2009 - .NET Matters (Page 118) MSDN Magazine - January 2009 - .NET Matters (Page 119) MSDN Magazine - January 2009 - { End Bracket } (Page 120) MSDN Magazine - January 2009 - { End Bracket } (Page Cover3) MSDN Magazine - January 2009 - { End Bracket } (Page Cover4)
For optimal viewing of this digital publication, please enable JavaScript and then refresh the page. If you would like to try to load the digital publication without using Flash Player detection, please click here.