Click to Rate and Give Feedback
Related Articles
Here the author introduces SQL Server Data Services, which exposes its functionality over standard Web service interfaces.

By David Robinson (July 2008)
Here the author answers questions regarding the Entity Framework and provides an understanding of how and why it was developed.

By Elisa Flasko (July 2008)
Here we present techniques for programmatic and declarative data binding and display with Windows Presentation Foundation.

By Josh Smith (July 2008)
Systems that handle failure without losing data are elusive. Learn how to achieve systems that are both scalable and robust.

By Udi Dahan (July 2008)
More ...
Articles by this Author
In this month’s installment of .NET Matters, columnist Stephen Toub answers reader questions concerning asynchronous I/O .

By Stephen Toub (July 2008)
This month Stephen Toub discusses asynchronous stream processing.

By Stephen Toub (March 2008)
This month Stephen Toub explains how to make the most of dual processors when running encryption and compression tasks.

By Stephen Toub (February 2008)
The author creates a managed wrapper to use the new IFileOperations interface in Windows Vista from managed code.

By Stephen Toub (December 2007)
Find out how to use finalizers as a way to warn developers who use your custom types when they are garbage collected without having been disposed of correctly.

By Stephen Toub (November 2007)
This month Stephen Toub discusses deadlocks that can occur when synchronizing threads.

By Stephen Toub (October 2007)
Stephen Toub and Shawn Farkas discuss creating an adapter that takes the functionality of RNGCryptoServiceProvider and adapts it to the interface of Random.

By Stephen Toub and Shawn Farkas (September 2007)
Stephen Toub gets nostalgic as he prepares to leave MSDN Magazine.

By Stephen Toub (August 2007)
More ...
Popular Articles
With custom form regions in Outlook you can pull in data from designated data sources and truly customize your users' Outlook 2007 experience.

By Steve Fox (Launch 2008)
Chris Tavares explains how the ASP.NET MVC Framework's Model View Controller pattern helps you build flexible, easily tested Web applications.

By Chris Tavares (March 2008)
Systems that handle failure without losing data are elusive. Learn how to achieve systems that are both scalable and robust.

By Udi Dahan (July 2008)
Here the author answers questions regarding the Entity Framework and provides an understanding of how and why it was developed.

By Elisa Flasko (July 2008)
More ...
Read the Blog
There are many things called threat modeling. Rather than argue about which is "the one true way," a good practice is to consider your needs and what your skills, abilities, and schedules are, and then work with a method that's best for you. In the July 2008 issue of MSDN Magazine, ...
Read more!
Want to develop games for Xbox Live? Want to get paid for it, too? Click on over to the XNA Team Blog to learn more about their initial rollout of the XNA Creators Club for XNA Game Studio. ...
Read more!
The Microsoft Entity Data Model (EDM), based on Dr. Peter Chen's Entity Relationship (ER) model, is the driving force behind the ADO.NET Entity Framework. The EDM is also the feature that most significantly differentiates the Entity Framework from other ORM-style technologies in the marketplace. In the July 2008 issue of MSDN ...
Read more!
System.IO.File is a handy helper class for reading and writing data, but its methods support only synchronous operation. Is there an easy way to provide File’s functionality for asynchronous file I/O? In the July 2008 issue of MSDN Magazine, Stephen Toub walks through several ...
Read more!
Remember .NET Terrarium, the interactive game meant to introduce .NET development techniques? Well, the Windows SDK team has released the source code for .NET Terrarium 2.0 on CodePlex. You can read more about this release on the Windows SDK blog and at Microsoft ...
Read more!
The Enumerable class plays an important role in every LINQ query you create. Because the Enumerable class's extension methods can process many other classes—including Array and List—you can use methods of the Enumerable class not only to create LINQ queries, but also to manipulate the behavior of arrays and other data structures. In the July 2008 issue of MSDN ...
Read more!
More ...
.NET Matters
ThreadPoolWait and HandleLeakTracker
Stephen Toub

Code download available at: NETMatters0410.exe (172 KB)
Browse the Code Online

Q I have a few tasks that I want to run asynchronously and simultaneously, and I want to wait for them all to finish before continuing. I've seen samples showing how to do this using Thread.Join, but those seem to conflict with the general recommendation to use the ThreadPool whenever possible rather than spinning up new threads. Is there a way to wait for operations queued to the ThreadPool to finish execution?
Q I have a few tasks that I want to run asynchronously and simultaneously, and I want to wait for them all to finish before continuing. I've seen samples showing how to do this using Thread.Join, but those seem to conflict with the general recommendation to use the ThreadPool whenever possible rather than spinning up new threads. Is there a way to wait for operations queued to the ThreadPool to finish execution?

A As you point out, the classic solution to this problem is to spawn a new thread for each operation, start each thread executing, and then join the main thread to each of the child threads. Such a solution might look something like the following:
ArrayList threads = new ArrayList();
for(int i=0; i<numOperationsToPerform; i++)
{
    Thread t = new Thread(new ThreadStart(DoSomething));
    t.Start();
    threads.Add(t);
}
foreach(Thread t in threads) t.Join();
A As you point out, the classic solution to this problem is to spawn a new thread for each operation, start each thread executing, and then join the main thread to each of the child threads. Such a solution might look something like the following:
ArrayList threads = new ArrayList();
for(int i=0; i<numOperationsToPerform; i++)
{
    Thread t = new Thread(new ThreadStart(DoSomething));
    t.Start();
    threads.Add(t);
}
foreach(Thread t in threads) t.Join();
Join operations block the calling thread until the target thread terminates (or until the specified time elapses if one of the other overloads of Join is used that accepts timeout parameters). Thus, you need to start all of the new threads before joining to any of them; otherwise, if you were to instead execute code like the following, you'd inadvertently be serializing all of the tasks:
for(int i=0; i<numOperationsToPerform; i++)
{
    Thread t = new Thread(new ThreadStart(DoSomething));
    t.Start();
    t.Join();
}
Spinning up new threads for every task may actually be the correct thing to do in your situation. But suppose you code this up and measure it, only to find that the use of new threads is the cause of performance problems (which could be the case if the number of simultaneous tasks is quite large). The .NET ThreadPool was created for situations like this.
A thread pool enables you to use threads more efficiently by providing your application with a set of worker threads that are managed by the system. All you have to do is use the ThreadPool.QueueUserWorkItem method to queue a WaitCallback delegate for execution, and the method referenced by the delegate will execute when a thread from the pool becomes available (or immediately if the thread pool has free threads available). Of course, since QueueUserWorkItem is asynchronous to your method (meaning that it returns immediately and most likely before your method has finished executing), as a user of the ThreadPool you don't know on which thread your method will execute, making it impossible to correctly join to it. Another solution is needed.
What you really need is a way for the main thread to keep track of all of the work items it's spawned and then for each work item to notify the main thread of its completion. A straightforward way to do this is to use an event object, such as System.Threading.ManualResetEvent. ManualResetEvent allows one thread to wait until another thread puts the event into a signaled state. Thus, the main thread can create an event, pass it to the worker thread, and wait for that event to be signaled. The worker thread can then signal the event when it has finished executing, as shown in the first half of Figure 1.
The second half of Figure 1 shows this same approach for supporting waiting on multiple work items. Each work item is given its own ManualResetEvent to signal on completion, and the main thread uses WaitHandle.WaitAll to block until all of the work item events have been set.
I've formalized this approach by writing the class shown in Figure 2. Using this class, you can execute code like the following:
ThreadPoolWait tpw = new ThreadPoolWait();
tpw.QueueUserWorkItem(new WaitCallback(DoSomething1));
tpw.QueueUserWorkItem(new WaitCallback(DoSomething2));
tpw.QueueUserWorkItem(new WaitCallback(DoSomething3));
tpw.WaitOne();
Under the covers, ThreadPoolWait handles all of the eventing logic necessary for the main thread to block until all of the worker threads have completed execution. When the ThreadPoolWait.QueueUserWorkItem method is called, it creates a new ManualResetEvent and stores it into an internal list of events. It then wraps this event and all of the parameters to the method into a simple state class. This state will be passed to the method invoked on a ThreadPool thread (methods to be executed on a ThreadPool thread must be compatible with the WaitCallback delegate, and thus must take a single object parameter).
ThreadPoolWait.QueueUserWorkItem finishes by delegating to ThreadPool.QueueUserWorkItem, but rather than passing to this method the caller-supplied WaitCallback, instead a new WaitCallback is created that wraps the private QueuedCallback.HandleCallback method (actually, HandleCallback is marked as public, but since its containing class, QueuedCallback, is private to ThreadPoolWait, HandleCallback is limited by the accessibility of its containing class). When executed by the ThreadPool, this method will raise the user-supplied callback with the user-supplied state, and upon completion will raise the ManualResetEvent created in QueueUserWorkItem.
This class works well in some situations, but unfortunately it has a few implementation drawbacks. First, each queued user work item is assigned its own ManualResetEvent. As a result, queueing hundreds of work items means hundreds of ManualResetEvents will be created. Second, and more importantly, WaitHandle.WaitAll has an upper bound to the number of handles on which it can wait; on my machine running Windows® XP, attempting to wait on more than 64 events results in a NotSupportedException being thrown. This means that with the implementation shown in Figure 1, either a maximum of 64 work items can be queued, or a different mechanism than WaitHandle.WaitAll must be used in order to monitor all of the events.
Another viable solution (but one that has similar problems to the approach just described) is to use delegates and a delegate's BeginInvoke method. As opposed to a delegate's Invoke method, which runs the referenced method on the current thread, BeginInvoke queues the method to be run on a ThreadPool thread. The IAsyncResult returned from BeginInvoke exposes a WaitHandle from its AsyncWaitHandle property (most likely a ManualResetEvent, although that is an internal implementation detail on which you shouldn't rely). Just as with the previously discussed approach, WaitHandle.WaitAll can be used to wait on this WaitHandle, which won't be signaled until the queued method has terminated, either successfully or by exception. This still suffers from the WaitHandle.WaitAll limit mentioned earlier.
A better solution that solves both of these problems is shown in Figure 3. Rather than creating one ManualResetEvent per work item, a single ManualResetEvent is used for the entire system. Whether or not the completion of a work item requires that this event be signaled is based on a counter that keeps track of how many work items that have been scheduled still have not finished executing. When a work item is scheduled, the count is incremented using System.Threading.Interlocked.Increment. And when a work item finishes, it decrements the count using Interlocked.Decrement; if the new value of the counter is zero, then the event is signaled.
Notice that the counter's value is initially set to one rather than to zero, which may seem odd. This is done to work around the problem of a work item finishing before all of the work items have been queued; in such a scenario, the event could be signaled before all work items have completed. As a workaround, the counter is initially set to one to ensure that the counter remains above zero until WaitOne is called. WaitOne begins by removing this extra value so that the count accurately represents the remaining work items to be completed. Note, too, that by the time WaitOne is called, all of the work items may have completed and thus the call WaitOne makes to decrement the counter may, in fact, bring the counter to zero. Thus, WaitOne has to perform the same check as the work item, signaling the ManualResetEvent if there is no outstanding work to be done.

Q I have some code that works with IDisposable objects, many of which hold onto unmanaged handles of one sort or another. In my unit tests I want to make sure that I've disposed of any object that requires disposal as soon as possible rather than forcing the finalizer to clean it up. What are some options available to me?
Q I have some code that works with IDisposable objects, many of which hold onto unmanaged handles of one sort or another. In my unit tests I want to make sure that I've disposed of any object that requires disposal as soon as possible rather than forcing the finalizer to clean it up. What are some options available to me?

A One common practice used both outside and inside of Microsoft is to take advantage of finalization for notification that an object wasn't cleaned up in a timely manner. As discussed in the .NET Matters column in the May 2004 edition of MSDN®Magazine finalizers should only be implemented in a release version when they're absolutely necessary to ensure that all unmanaged resources are released properly.
A One common practice used both outside and inside of Microsoft is to take advantage of finalization for notification that an object wasn't cleaned up in a timely manner. As discussed in the .NET Matters column in the May 2004 edition of MSDN®Magazine finalizers should only be implemented in a release version when they're absolutely necessary to ensure that all unmanaged resources are released properly.
However, code can be added to a finalizer that alerts the developer as to when it's run (this should only be done in a debug version unless you have very special circumstances that warrant otherwise). In addition, for classes that implement IDisposable but that don't necessitate a finalizer (for example, a managed class that only holds references to other managed classes that implement IDisposable), a notification finalizer could be conditionally compiled into the class in debug builds.
As an example of classes that were implemented to follow this pattern, take a look at the finalizer for FileStream as coded in the Shared Source Common Language Infrastructure (SSCLI), which is available for download at http://msdn.microsoft.com/net/sscli:
~FileStream()
{
    if (_handleProtector != null) {
        BCLDebug.Correctness(_handleProtector.IsClosed, 
            "You didn't close a FileStream & it got finalized.  Name:\""
            + _fileName + "\"");
        Dispose(false);
    }
}
If _handleProtector is not null, then the FileStream was not Disposed, and a debug assert is raised. Of course, calls to BCLDebug.Correctness are only compiled into _DEBUG builds, as dictated by the System.Diagnostics.ConditionalAttribute applied to the Correctness method.
This solution works very well when you're writing the class in question. But what if someone else has written the class and compiled it, and now you're using the assembly they've provided to you? In such a situation, certain types of leaks are easier to discover than others. For example, the base class shown in Figure 4 can be used to help track down native handle leaks using a very simple process: take a snapshot of the handle count before you run the leaky code in question, run the code, take a snapshot afterwards, and then compare the before and after numbers. This approach isn't foolproof and in some situations could result in both false positives and negatives, but in the general case it proves to be a very useful tactic while debugging.
How do you use the code in Figure 4? The HandleLeakTracker class shown is an abstract base class, so it is assumed you will derive your own specialized class from this in order to track the specific type of resource in which you're interested. For example, if I want to ensure that a specific section of code does not leak a handle opened by the process, I can derive a new class from HandleLeakTracker. This class overrides the HandleCount abstract method and returns the result of calling Process.HandleCount for the current Process:
public class ProcessHandleLeakTracker : HandleLeakTracker {
    protected override int HandleCount { 
        get {
            using (Process p = Process.GetCurrentProcess()) {
                return p.HandleCount; 
            }
        }
    }
}
Since HandleLeakTracker implements IDisposable, I can surround the leaky code in question with a using block as follows:
using(new ProcessHandleLeakTracker())
{
    StreamWriter w = new StreamWriter(@"C:\test.txt");
    w.WriteLine("Hello, World!");
}
The constructor of HandleLeakTracker stores the current HandleCount. The code in the using block runs, and then the Dispose method (executed from the finally block generated by the C# compiler as part of the using semantics) retrieves the new handle count and performs the comparison. The virtual Assert method uses Debug.Fail to signal any discrepancies.
Note, too, that both the constructor and the Dispose method can call HandleLeakTracker.RunGC depending on the Boolean parameters specified in the constructor. By default, a garbage collection is run before the handle count is initially taken so that a garbage collection that takes place while the code in question is running won't throw off the numbers. Of course, even with this precaution, situations arise which can result in a skewed handle count, such as a multithreaded application in which another thread is creating and destroying handles while the leak detection code is executing, or the garbage collector running arbitrarily during the using block and leading you into a false sense of security. The beauty of using this in your unit tests, though, is that while it won't always point out problems that exist, there's a good chance it'll help you find more than you otherwise would have discovered.
Other variants of this class are possible, such as a HandleLeakTracker-derived class that uses the GetGuiResources function exposed from User32.dll to track Graphical Device Interface (GDI) and User object leaks, shown here:
public class GuiHandleLeakTracker : HandleLeakTracker {
    protected override int HandleCount
    {
        get {
            using (Process p = Process.GetCurrentProcess())
                return GetGuiResources(p.Handle, 0) + 
                    GetGuiResources(p.Handle, 1);
        }
    }
    [DllImport("User32")]
    private static extern int GetGuiResources(
        IntPtr hProcess, int uiFlags);
}
The base class could even be modified to support snapshot-capable resources besides handles, or could be integrated with a kernel-mode driver capable of reporting exactly which handles are open, thus allowing the class to determine not only how many handles are erroneously open but also to pinpoint exactly which ones were leaked. As usual, the possibilities are practically endless, and I'd be interested to hear what other solutions you find.

Send your questions and comments to  netqa@microsoft.com.


Stephen Toub is the Technical Editor for MSDN Magazine.

Page view tracker