Beruflich Dokumente
Kultur Dokumente
Calling
functions asynchronously causes the system to execute them in the background on a secondary
thread while the calling function continues to do other work. In a typical (synchronous) function
call, the function is executed right away on the same thread that made the call. The calling
function waits for the call to complete and receives the results of the call before continuing. By
contrast, when you make an asynchronous call, you retrieve the results of the asynchronous call
later. This article demonstrates how to do this by using Visual C#.
Requirements
The following list outlines the recommended hardware, software, network infrastructure, and
service packs that are required:
This article assumes that you are familiar with the following topics:
The following is an example of a delegate and its BeginInvoke() and EndInvoke() methods:
// The following delegate
delegate string MethodDelegate(int iCallTime, out int iExecThread)
There are four common ways to use BeginInvoke() and EndInvoke() to make asynchronous
calls. After you call BeginInvoke(), you can:
Obtain a WaitHandle that is provided by the IAsyncResult object, use its WaitOne
method to block until the WaitHandle is signaled, and then call EndInvoke().
Poll the IAsyncResult object to determine when the asynchronous call has completed,
and then call EndInvoke().
Have the system call a callback function that you specify. This callback function calls
EndInvoke() and processes the results of the asynchronous call when it completes.
The following code samples demonstrate these call patterns and contrast them with making a
synchronous call by using the following function:
string LongRunningMethod (int iCallTime, out int iExecThread)
{
Thread.Sleep (iCallTime) ;
iExecThread = AppDomain.GetCurrentThreadId ();
return "MyCallTime was " + iCallTime.ToString() ;
}
LongRunningMethod() simulates a function that runs for long time by sleeping. It returns the
sleep time and the ID of the thread that executes it. If you call it asynchronously, you find that
the thread ID of the executing thread is different from that of the calling thread.
The first step is to define the delegate that wraps the function:
Later, this class demonstrates how to make asynchronous calls. Initially, however, it only
contains the DemoSyncCall() method, which demonstrates how to call the delegate
synchronously.
34. Add the following code in the body of the Main function that Visual Studio automatically
creates in your project:
35. static void Main(string[] args)
36. {
37.
AsyncDemo ad = new AsyncDemo () ;
38.
ad.DemoSyncCall() ;
39. }
20. Edit the source code for Main so that it contains the following code:
21. static void Main(string[] args)
22. {
23.
AsyncDemo ad = new AsyncDemo () ;
24.
ad.DemoEndInvoke() ;
25. }
In this section, the sample calls the method asynchronously and waits for a WaitHandle before it
calls EndInvoke(). The IAsyncResult that is returned by BeginInvoke() has an
AsyncWaitHandle property. This property returns a WaitHandle that is signaled when the
asynchronous call completes. Waiting on a WaitHandle is a common thread synchronization
technique. The calling thread waits on the WaitHandle by using the WaitOne() method of the
WaitHandle. WaitOne() blocks until the WaitHandle is signaled. When WaitOne() returns,
you can do some additional work before you call EndInvoke(). As in the previous sample, this
technique is useful for executing file or network operations that would otherwise block the
calling main thread.
1. Add a function named DemoWaitHandle() to the AsyncDemo class. The
DemoWaitHandle() function demonstrates how to call the delegate asynchronously.
2. public void DemoWaitHandle ()
3. {
4.
string s ;
5.
int iExecThread;
6.
7.
MethodDelegate dlgt = new MethodDelegate (this.LongRunningMethod) ;
8.
9.
// Initiate the asynchronous call.
10.
IAsyncResult ar = dlgt.BeginInvoke(3000, out iExecThread,
null, null);
11.
12.
// Do some useful work here. This would be work you want to
have
13.
// run at the same time as the asynchronous call.
14.
15.
// Wait for the WaitHandle to become signaled.
16.
ar.AsyncWaitHandle.WaitOne() ;
17.
18.
// Get the results of the asynchronous call.
19.
s = dlgt.EndInvoke (out iExecThread, ar) ;
20.
21.
MessageBox.Show (string.Format ("The delegate call returned
the string:
\"{0}\",
22.
and the number {1}", s,
iExecThread.ToString() ) );
23. }
24. Edit the source code for Main so that it contains the following code:
25. static void Main(string[] args)
26. {
27.
AsyncDemo ad = new AsyncDemo () ;
28.
ad.DemoWaitHandle () ;
29. }
22. Edit the source code for Main. Replace the content of the function with the following
code:
23. static void Main(string[] args)
24. {
25.
AsyncDemo ad = new AsyncDemo () ;
26.
ad.DemoPolling () ;
27. }
26.
27.
28.
32. Edit the source code for Main. Replace the content of the function with the following
code:
33. static void Main(string[] args)
34. {
35.
AsyncDemo ad = new AsyncDemo () ;
36.
ad.DemoCallback() ;
37. }