CHAPTER 19 MULTITHREADED, PARALLEL, AND ASYNC PROGRAMMING
method in a synchronous manner, the Main() method will not print out the result of the operation until
the Add() method has completed.
Next, note that the Main() method is obtaining access to the current thread (via
Thread.CurrentThread) and printing out the ID of the thread via the ManagedThreadId property. This
same logic is repeated in the static Add() method. As you might suspect, given that all the work in this
application is performed exclusively by the primary thread, you find the same ID value displayed to the
console:
***** Synch Delegate Review *****
Main() invoked on thread 1.
Add() invoked on thread 1.
Doing more work in Main()!
10 + 10 is 20.
Press any key to continue . . .
When you run this program, you should notice that a five-second delay takes place before you see
the final Console.WriteLine() logic in Main() execute. Although many (if not most) methods may be
called synchronously without ill effect, .NET delegates can be instructed to call their methods
asynchronously if necessary.
Source Code The SyncDelegateReview project is located under the Chapter 19 subdirectory.
The Asynchronous Nature of Delegates
If you are new to the topic of multithreading, you might wonder what exactly an asynchronous method
invocation is all about. As you are no doubt fully aware, some programming operations take time.
Although the previous Add() was purely illustrative in nature, imagine that you built a single-threaded
application that is invoking a method on a remote object, calling a method performing a long-running
database query, downloading a large document, or writing 500 lines of text to an external file. While
performing these operations, the application could appear to hang for some amount of time. Until the
task at hand has been processed, all other aspects of this program (such as menu activation, toolbar
clicking, or console output) are suspended (which can aggravate users).
Therefore, the question is, how can you tell a delegate to invoke a method on a separate thread of
execution to simulate numerous tasks performing “at the same time”? The good news is that every .NET
delegate type is automatically equipped with this capability. The even better news is that you are not
required to directly dive into the details of the System.Threading namespace to do so (although these
entities can quite naturally work hand in hand).
The BeginInvoke() and EndInvoke() Methods
When the C# compiler processes the delegate keyword, the dynamically generated class defines two
methods named BeginInvoke() and EndInvoke(). Given the definition of the BinaryOp delegate, these
methods are prototyped as follows:
701