Module 14 (Optional): Threading and Asynchronous Programming |
83 |
|
|
|
The output that is produced by running the code is similar to the following:
Doing Synchronous Read
Synchronous Read Data:! 0123456789012345678901234567890123456789! 0123456789012345678901234567890123456789! 0123456789012345678901234567890123456789! 0123456789012345678901234567890123456789! 0123456789012345678901234567890123456789! 0123456789012345678901234567890123456789! 0123456789012345678901234567890123456789! 0123456789012345678901234567890123456789! 0123456789012345678901234567890123456789! 0123456789012345678901234567890123456789! 0123456789012345678901234567890123456789! 0123456789012345678901234567890123456789! 01234567890123456789012345678901
Doing Callback Asynchronous Read
Asynchronous Callback Read Filename: test.txt Data:!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
01234567890123456789012345678901
Doing Poll Asynchronous Read
Asynchronous Poll Read Filename: test.txt Data:!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
01234567890123456789012345678901
(Code continued on the following page.)
84 |
Module 14 (Optional): Threading and Asynchronous Programming |
Doing End Method Asynchronous Read
Asynchronous End Read Filename: test.txt Data:!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
01234567890123456789012345678901
Doing Wait Asynchronous Read
Asynchronous Wait Read Filename: test.txt Data:!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
0123456789012345678901234567890123456789!
01234567890123456789012345678901
Module 14 (Optional): Threading and Asynchronous Programming |
85 |
|
|
|
Asynchronous Delegates
Topic Objective
To describe how to use delegate objects to make asynchronous calls.
Lead-in
You can make an asynchronous method call on an object even if the object’s class does not provide explicit support for asynchronous operations by using the asynchronous methods of a delegate object.
!Delegate object provides the ability to call a synchronous method in an asynchronous manner
#Compiler generates synchronous invoke method and asynchronous methods: BeginInvoke and EndInvoke
!Asynchronous calls follow the design pattern
#Start operation with BeginInvoke
#Use callback, polling, call to EndInvoke, or wait to determine completion
#Call EndInvoke to get results
*****************************ILLEGAL FOR NON-TRAINER USE******************************
You can make an asynchronous method call on an object even if the object’s class does not provide explicit support for asynchronous operations by using the asynchronous methods of a delegate object.
Calling a synchronous method asynchronously
For each delegate class the Visual C# compiler generates BeginInvoke and EndInvoke methods that provide the ability to call a synchronous target method in an asynchronous manner.
If the BeginInvoke method is called, the runtime queues the request and returns immediately to the caller. The target method will be called on a thread from the thread pool. The original thread that submitted the request is free to continue executing in parallel to the target method, which is running on a thread pool thread.
If a callback has been specified on BeginInvoke, it is called when the target method returns. In the callback, the EndInvoke method is used to obtain the return value and the in/out parameters. If the callback is not specified on BeginInvoke, you can use the other asynchronous design pattern techniques, for example polling, on the original thread that submitted a request.
86 |
Module 14 (Optional): Threading and Asynchronous Programming |
Using an asynchronous delegate
In the following example, which factorizes a number, you can see how to use a delegate to make an asynchronous call.
The code for this demonstration is located in <install folder>\Democode\ Mod14\Demo14.7.
In this example, an asynchronous call is invoked on the Factorize method in the PrimeFactorizer class, which is declared as follows:
public class PrimeFactorizer
{
public bool Factorize( int factorizableNum, ref int primefactor1, ref int primefactor2)
{
// code to factorize the number
}
}
First a delegate for the Factorize is defined:
public delegate bool FactorizeDelegate( int factorizableNum,
ref int primefactor1, ref int primefactor2);
When the compiler emits the FactorizeDelegate delegate class after parsing its definition, it generates the BeginInvoke and EndInvoke methods, in addition to the Invoke method. The BeginInvoke and EndInvoke methods follow the asynchronous design pattern’s method signatures, as follows:
public class FactorizeDelegate: delegate
{
public bool Invoke(
int factorizableNum, ref int primefactor1, ref int primefactor2);
//The following code was supplied by the compiler. public IAsyncResult BeginInvoke(
int factorizableNum, ref int primefactor1, ref int primefactor2, AsyncCallback cb, Object AsyncState
);
//The following code was supplied by the compiler. public bool EndInvoke(
ref int primefactor1, ref int primefactor2, IAsyncResult ar);
}
Module 14 (Optional): Threading and Asynchronous Programming |
87 |
|
|
|
Next, the method to be called when the operation completes is defined:
public class ProcessFactorizedNumber
{
private int _ulNumber;
public ProcessFactorizedNumber(int number)
{
_ulNumber = number;
}
// the qualifier is one-way, see Note [OneWayAttribute()]
public void FactorizedResults(IAsyncResult ar)
{
int factor1=0, factor2=0;
//Extract the delegate from the AsyncResult. FactorizeDelegate fd = (FactorizeDelegate)((AsyncResult)ar).AsyncDelegate;
//Obtain the result.
fd.EndInvoke(ref factor1, ref factor2, ar);
// Output results. Console.WriteLine(
"On CallBack: Factors of {0} : {1} {2}", _ulNumber, factor1, factor2);
}
}
Note The OneWayAttribute marks a method as one way, without a return value and out or ref parameters. When one-way methods are called, no reply message, status, or other information is expected.
88 |
Module 14 (Optional): Threading and Asynchronous Programming |
The asynchronous operation is started by calling BeginInvoke as follows:
public void FactorizeNumber1()
{
//create the necessary arguments
//delegate to method to be called asynchronously PrimeFactorizer pf = new PrimeFactorizer(); FactorizeDelegate fd = new
FactorizeDelegate(pf.Factorize);
//arguments for the Factorize method
int factorizableNum = 1000589023, temp=0;
//create the callback delegate
//to be called when the call completes
//first create an instance of the class which
//contains the callback method ProcessFactorizedNumber fc = new
ProcessFactorizedNumber(factorizableNum);
//then create an AsyncCallback delegate to the method AsyncCallback cb = new
AsyncCallback(fc.FactorizedResults);
//Asynchronously invoke the Factorize method. IAsyncResult ar = fd.BeginInvoke(
factorizableNum, ref temp,
ref temp, cb, null);
//
// Do some other useful work. //. . .
}
Module 14 (Optional): Threading and Asynchronous Programming |
89 |
|
|
|
An alternative approach to using a callback function is to wait for completion, as shown in the following code:
public void FactorizeNumber2()
{
PrimeFactorizer pf = new PrimeFactorizer(); FactorizeDelegate fd = new
FactorizeDelegate(pf.Factorize);
int factorizableNum = 1000589023, temp=0;
// Asynchronously invoke the Factorize method on pf. IAsyncResult ar = fd.BeginInvoke(
factorizableNum, ref temp,
ref temp, null, null);
ar.AsyncWaitHandle.WaitOne(10000, false);
if (ar.IsCompleted)
{
int factor1=0, factor2=0;
// Obtain the result.
fd.EndInvoke(ref factor1, ref factor2, ar);
// Output results.
Console.WriteLine(
"After Using Wait Handle: Factors of {0}: {1} {2}", factorizableNum, factor1, factor2);
}
}
90 |
Module 14 (Optional): Threading and Asynchronous Programming |
Multimedia: Asynchronous Programming
Topic Objective
To illustrate asynchronous programming using Delegate objects.
Lead-in
This animation illustrates the
.NET Framework common language runtime’s support for asynchronous programming using Delegate objects.
*****************************ILLEGAL FOR NON-TRAINER USE******************************
To launch the animation, click the button in the lowerleft corner of the slide.
This animation illustrates the .NET Framework common language runtime support for asynchronous programming using Delegate objects.
Module 14 (Optional): Threading and Asynchronous Programming |
91 |
|
|
|
Demonstration: Using a Delegate
Topic Objective
To demonstrate how to use a delegate object to make asynchronous calls.
Lead-in
In this demonstration, you will see how to use a delegate object to make asynchronous calls.
*****************************ILLEGAL FOR NON-TRAINER USE******************************
This demonstration shows how to use a delegate object to make asynchronous calls. The asynchronous call is made by using a callback method and by waiting for the completion event.
The code for this demonstration is located in <install folder>\Democode\
Mod14\Demo14.7.
The output is similar to the following:
On CallBack: Factors of 1000589023 : 7 142941289
After Using Wait Handle : Factors of 1000589023 : 7 142941289
92 |
Module 14 (Optional): Threading and Asynchronous Programming |
Lab 14: Working With Multithreaded Applications
Topic Objective
To introduce the lab.
Lead-in
In this lab, you will create thread-safe code that has both System.Thread.Timer and background thread objects. In addition you will make asynchronous calls using delegates.
*****************************ILLEGAL FOR NON-TRAINER USE******************************
Explain the lab objectives. |
Objectives |
|
|
After completing this lab, you will be able to: |
|
! Create thread-safe methods using the C# lock keyword. |
|
! Create, start, and dispose of a System.Thread.Timer object to periodically |
|
perform an action. |
|
! Create, start, and interrupt a background thread. |
|
! Make an asynchronous method call by using delegates and a callback |
|
method according to the .NET Framework asynchronous design pattern. |
|
Lab Setup |
Starter and solution files are associated with this lab. The starter files are in the folder <install folder>\Labs\Lab14\Starter. The solution files for this lab are in the folder <install folder>\Labs\Lab14\Solution.