CHAPTER 19 MULTITHREADED, PARALLEL, AND ASYNC PROGRAMMING
To obtain this data within the scope of AddComplete(), make use of the AsyncState property of the
incoming IAsyncResult parameter. Notice that an explicit cast will be required; therefore, the primary
and secondary threads must agree on the underlying type returned from AsyncState.
static void AddComplete(IAsyncResult itfAR)
{
...
// Retrieve the informational object and cast it to string.
string msg = (string)itfAR.AsyncState;
Console.WriteLine(msg);
isDone = true;
}
Here is the output of the final iteration:
***** AsyncCallbackDelegate Example *****
Main() invoked on thread 1.
Add() invoked on thread 3.
Working....
Working....
Working....
Working....
Working....
AddComplete() invoked on thread 3.
Your addition is complete
10 + 10 is 20.
Main() thanks you for adding these numbers.
Now that you understand how a .NET delegate can be used to automatically spin off a secondary
thread of execution to handle an asynchronous method invocation, let’s turn our attention to directly
interacting with threads using the System.Threading namespace. Recall that this namespace was the
original .NET threading API that shipped since version 1.0.
Source Code The AsyncCallbackDelegate project is located under the Chapter 19 subdirectory.
The System.Threading Namespace
Under the .NET platform, the System.Threading namespace provides a number of types that enable the
direct construction of multithreaded applications. In addition to providing types that allow you to
interact with a particular CLR thread, this namespace defines types that allow access to the CLRmaintained thread pool, a simple (non–GUI-based) Timer class, and numerous types used to provide
synchronized access to shared resources. Table 19-1 lists some of the important members of this
namespace. (Be sure to consult the .NET Framework 4.5 SDK documentation for full details.)
709