Overview
Delegates enable calling any synchronous method in an asynchronous manner.
How it Works
The CLR automatically defines BeginInvoke
and EndInvoke
methods for a delegate with the appropriate signature. This can then be used like the APM model.
BeginInvoke
- Has same parameters as method to be executed asynchronously, plus:
- an
AsyncCallback
delegate that references the method to be called when the async call completes - a user-defined object that passes information into the callback method
- an
- Returns an
IAsyncResult
EndInvoke
- If called before async call is complete, blocks calling thread until it is.
- Returns the result of the async call.
Process
- Call
BeginInvoke
- Either:
- Do some work and then call
EndInvoke
- Wait
- Obtain a
WaitHandle
fromIAsyncResult.AsyncWaitHandle
- Use it
WaitOne
method to block until theWaitHandle
is signaled - Call
EndInvoke
- Obtain a
- Poll
- Poll
IAsyncResult
to determine when the async call has completed - Call
EndInvoke
- Poll
- Pass a delegate for a callback method to
BeginInvoke
- This method is executed when the async call completes.
- Have the callback method call
EndInvoke
.
- Do some work and then call
Example
public class SomeClass
{
public string SomeLongRunningMethod(int callDuration, out int threadId)
{
Thread.Sleep(callDuration);
threadId = Thread.CurrentThread.ManagedThreadId;
return $"Call time {callDuration.ToString()}";
}
public delegate string SomeDelegate(int callDuration, out int threadId);
}
public class SomeOtherClass
{
public static void Main()
{
int threadId;
SomeClass c = new();
// Create the delegate:
SomeDelegate caller = new(c.SomeLongRunningMethod);
// Initiate the async call:
IAsyncResult result = caller.BeginInvoke(3000, out threadId, null, null);
// End the async call:
string returnValue = caller.EndInvoke(out threadId, result);
}
}