Examples of three types of invocation of C delegate (synchronous invocation asynchronous invocation asynchronous callback)
- 2020-05-24 06:04:28
- OfStack
First, define one delegate and the following three methods to be called by the example through the code:
public delegate int AddHandler(int a,int b);
public class Add class
{
public static int Add(int a, int b)
{
Console.WriteLine(" Start counting: " + a + "+" + b);
Thread.Sleep(3000); // Simulate this method running 3 seconds
Console.WriteLine(" Calculation complete! ");
return a + b;
}
}
A synchronous invocation
The Invoke method of the delegate is used to make synchronous calls. Synchronous calls can also be called block calls, which block the current thread, execute the call, and continue down after the call is complete.
public class A synchronous invocation
{
static void Main()
{
Console.WriteLine("===== A synchronous invocation SyncInvokeTest =====");
AddHandler handler = new AddHandler( Add class .Add);
int result = handler.Invoke(1, 2);
Console.WriteLine(" Move on to something else... ");
Console.WriteLine(result);
Console.ReadKey();
}
}
Synchronous calls block threads, and if you're calling a heavy workload (such as a large number of IO operations), you may have to pause the program for a long time, resulting in a poor user experience, where asynchronous calls are necessary.
The asynchronous call
Instead of blocking the thread, the asynchronous call plugs the call into the thread pool, and either the main thread or the UI thread can continue executing. The asynchronous invocation of the delegate is implemented through BeginInvoke and EndInvoke.
public class The asynchronous call
{
static void Main()
{
Console.WriteLine("===== The asynchronous call AsyncInvokeTest =====");
AddHandler handler = new AddHandler( Add class .Add);
//IAsyncResult: Asynchronous operation interface (interface)
//BeginInvoke: entrust (delegate) the 1 The start of an asynchronous method
IAsyncResult result = handler.BeginInvoke(1, 2, null, null);
Console.WriteLine(" Move on to something else... ");
// Asynchronous operation return
Console.WriteLine(handler.EndInvoke(result));
Console.ReadKey();
}
}
As you can see, the main thread doesn't wait, but runs straight down. But the problem remains that when the main thread reaches EndInvoke, if the call does not end (which is likely), the thread will still be blocked while waiting for the result of the call.
Asynchronous delegate, can also be written as follows:
Action < object > action=(obj)= > method(obj);
action.BeginInvoke(obj,ar= > action.EndInvoke(ar),null);
One operation can be completed in two simple sentences.
An asynchronous callback
With the callback function, the callback function is automatically called when the call ends, resolving the situation where the thread is still blocked while waiting for the result of the call.
public class An asynchronous callback
{
static void Main()
{
Console.WriteLine("===== An asynchronous callback AsyncInvokeTest =====");
AddHandler handler = new AddHandler( Add class .Add);
// Asynchronous operation interface ( Pay attention to BeginInvoke Different methods! )
IAsyncResult result = handler.BeginInvoke(1,2,new AsyncCallback( The callback function ),"AsycState:OK");
Console.WriteLine(" Move on to something else... ");
Console.ReadKey();
}
static void The callback function (IAsyncResult result)
{
//result It's an addition class .Add() method
//AsyncResult is IAsyncResult Of the interface 1 Three implementation classes, space: System.Runtime.Remoting.Messaging
//AsyncDelegate Properties can be cast to the actual class of a user-defined delegate.
AddHandler handler = (AddHandler)((AsyncResult)result).AsyncDelegate;
Console.WriteLine(handler.EndInvoke(result));
Console.WriteLine(result.AsyncState);
}
}
The type of delegate I defined is AddHandler, and in order to access AddHandler.EndInvoke, I must cast the asynchronous delegate to AddHandler. You can call MAddHandler.EndInvoke from the asynchronous callback function (of type AsyncCallback) to get the results of the original submission of AddHandler.BeginInvoke.
Question:
(1) int result = handler. Invoke(1,2);
Why are the parameters and return values of Invoke identical to the AddHandler delegate?
A: the parameters of the Invoke method are simple, 1 delegate, 1 parameter table (optional), and the main function of the Invoke method is to help you call the method specified by the delegate from the UI thread. The Invoke method first checks to see if the calling thread (that is, the current thread) is the UI thread. If so, it executes the delegate pointing method directly. If not, it switches to the UI thread and executes the delegate pointing method. Whether the current thread is an UI thread or not, Invoke blocks until the method pointed to by the delegate is executed, then switches back to the calling thread (if needed) and returns.
So the parameters and return value of the Invoke method and the delegate that calls it should be 1.
(2) IAsyncResult result = handler.BeginInvoke (1,2,null,null);
BeginInvoke: start 1 asynchronous request, call 1 thread in the thread pool to execute,
Return the IAsyncResult object (the asynchronous core). IAsyncResult simply says that it is an interface that stores the state of the asynchronous operation and can also be used to end the current asynchrony.
Note: BeginInvoke and EndInvoke must be called in pairs. Even if no return value is required, EndInvoke must be called, otherwise a memory leak may occur.
(3) IAsyncResult.AsyncState attribute:
Gets a user-defined object that qualifies or contains information about asynchronous operations. Such as:
static void AddComplete(IAsyncResult result)
{
AddHandler handler = (AddHandler)result.AsyncState;
Console.WriteLine(handler.EndInvoke(result));
}
The complete code is as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Runtime.Remoting.Messaging;
namespace ConsoleTest
{
public delegate int AddHandler(int a,int b);
public class Add class
{
public static int Add(int a, int b)
{
Console.WriteLine(" Start counting: " + a + "+" + b);
Thread.Sleep(3000); // Simulate this method running 3 seconds
Console.WriteLine(" Calculation complete! ");
return a + b;
}
}
public class A synchronous invocation
{
static void Main()
{
Console.WriteLine("===== A synchronous invocation SyncInvokeTest =====");
AddHandler handler = new AddHandler( Add class .Add);
int result = handler.Invoke(1, 2);
Console.WriteLine(" Move on to something else... ");
Console.WriteLine(result);
Console.ReadKey();
}
}
public class The asynchronous call
{
static void Main()
{
Console.WriteLine("===== The asynchronous call AsyncInvokeTest =====");
AddHandler handler = new AddHandler( Add class .Add);
//IAsyncResult: Asynchronous operation interface (interface)
//BeginInvoke: entrust (delegate) the 1 The start of an asynchronous method
IAsyncResult result = handler.BeginInvoke(1, 2, null, null);
Console.WriteLine(" Move on to something else... ");
// Asynchronous operation return
Console.WriteLine(handler.EndInvoke(result));
Console.ReadKey();
}
}
public class An asynchronous callback
{
static void Main()
{
Console.WriteLine("===== An asynchronous callback AsyncInvokeTest =====");
AddHandler handler = new AddHandler( Add class .Add);
// Asynchronous operation interface ( Pay attention to BeginInvoke Different methods! )
IAsyncResult result = handler.BeginInvoke(1,2,new AsyncCallback( The callback function ),"AsycState:OK");
Console.WriteLine(" Move on to something else... ");
Console.ReadKey();
}
static void The callback function (IAsyncResult result)
{
//result It's an addition class .Add() method
//AsyncResult is IAsyncResult Of the interface 1 Three implementation classes, reference space: System.Runtime.Remoting.Messaging
//AsyncDelegate Properties can be cast to the actual class of a user-defined delegate.
AddHandler handler = (AddHandler)((AsyncResult)result).AsyncDelegate;
Console.WriteLine(handler.EndInvoke(result));
Console.WriteLine(result.AsyncState);
}
}
}