CHAPTER 19 MULTITHREADED, PARALLEL, AND ASYNC PROGRAMMING
static void Add(object data)
{
if (data is AddParams)
{
Console.WriteLine("ID of thread in Add(): {0}",
Thread.CurrentThread.ManagedThreadId);
AddParams ap = (AddParams)data;
Console.WriteLine("{0} + {1} is {2}",
ap.a, ap.b, ap.a + ap.b);
// Tell other thread we are done.
waitHandle.Set();
}
}
Source Code The AddWithThreads project is included under the Chapter 19 subdirectory.
Foreground Threads and Background Threads
Now that you have seen how to programmatically create new threads of execution using the
System.Threading namespace, let’s formalize the distinction between foreground threads and
background threads.
•
Foreground threads have the ability to prevent the current application from
terminating. The CLR will not shut down an application (which is to say, unload
the hosting AppDomain) until all foreground threads have ended.
•
Background threads (sometimes called daemon threads) are viewed by the CLR as
expendable paths of execution that can be ignored at any point in time (even if
they are currently laboring over some unit of work). Thus, if all foreground threads
have terminated, any and all background threads are automatically killed when
the application domain unloads.
It is important to note that foreground and background threads are not synonymous with primary
and worker threads. By default, every thread you create via the Thread.Start() method is automatically
a foreground thread. Again, this means that the AppDomain will not unload until all threads of execution
have completed their units of work. In most cases, this is exactly the behavior you require.
For the sake of argument, however, assume that you want to invoke Printer.PrintNumbers() on a
secondary thread that should behave as a background thread. Again, this means that the method
pointed to by the Th