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);
        }
    }
}


Related articles: