On the sharing of three calls of C ා delegate

1, Synchronous call

1. Synchronous calls are executed in code order
2. Synchronous call will block the thread. If you want to call a heavy work (such as a large number of IO operations), it may make the program pause for a long time, resulting in a bad user experience. At this time, asynchronous call is necessary.

Here's a chestnut:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Threading;

namespace Test
{
    public delegate int AddHandler(int a, int b);
    public class Calc
    {
        public static int Add(int a, int b)
        {
            Console.WriteLine("Start calculation:" + a + "+" + b);
            Thread.Sleep(3000); //Simulate this method to run for three seconds
            Console.WriteLine("Calculation complete!");
            return a + b;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
              Console.WriteLine("===== Synchronous call SyncInvokeTest =====");
            AddHandler handler = new AddHandler(Calc.Add);
            int result = handler.Invoke(1, 2);
            Console.WriteLine("Continue to do other things...");
            Console.WriteLine(result);
            Console.ReadKey();
        }    
    }
}

*Q: Why are the parameters and return values of Invoke the same as the AddHandler delegate?
*Answer: the parameters of Invoke method are very simple, one delegate, one parameter table (optional),
The main function of Invoke method is to help you call the method specified by the delegate on the UI thread.
The Invoke method first checks whether the calling thread (that is, the current thread) is the UI thread,
If so, execute the method the delegate points to directly, if not, it will switch to the UI thread,
Then execute the method that the delegate points to. Whether the current thread is a UI thread or not,
Invoke blocks until the method pointed to by the delegate is executed, and then switches back to the
Thread, if required, returns.
Therefore, the parameters and return values of the Invoke method should be the same as those of the calling delegate.







2, Asynchronous call

1. Asynchronous calls do not block threads, but plug calls into the thread pool,
2. The program main thread or UI thread can continue execution.
3. Asynchronous calls to delegates are implemented through BeginInvoke and EndInvoke.

Here's a chestnut:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Threading;

namespace Test
{
    public delegate int AddHandler(int a, int b);
    public class Calc
    {
        public static int Add(int a, int b)
        {
            Console.WriteLine("Start calculation:" + a + "+" + b);
            Thread.Sleep(3000); //Simulate this method to run for three seconds
            Console.WriteLine("Calculation complete!");
            return a + b;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("===== Asynchronous call AsyncInvokeTest =====");
            AddHandler handler1 = new AddHandler(Calc.Add);
            //IAsyncResult: Asynchronous operation interface(interface)
            //BeginInvoke: entrust(delegate)The beginning of an asynchronous method of
            IAsyncResult result1 = handler1.BeginInvoke(1, 2, null, null);
 
            Console.WriteLine("Continue to do other things 1...");
            //Asynchronous operation return
            Console.WriteLine(handler1.EndInvoke(result1));//Will wait for the addition class to calculate. If not, the thread will be blocked
            Console.WriteLine("Continue to do other things 2...");
            Console.ReadKey();
        }    
    }
}

be careful:
*BeginInvoke: start an asynchronous request, call a thread in the thread pool to execute,
*Returns the IAsyncResult object (the core of asynchrony). IAsyncResult is simple,
*An interface that stores the status information of an asynchronous operation, or it can be used to end the current asynchronous operation.
*Note: BeginInvoke and EndInvoke must be called in pairs, even if no return value is required,
*However, EndInvoke must be called, otherwise it may cause memory leak.




result:

As you can see, the main thread does not wait, but runs directly down.
But the problem still exists. When the main thread runs to EndInvoke, if the call does not end at this time (this is likely to happen), then in order to wait for the call result, the thread will still be blocked.

3, Asynchronous callback

With callback function, when the call is finished, the callback function will be called automatically, which solves the problem that the thread is still blocked in order to wait for the call result.

Here's a chestnut:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Threading;

namespace Test
{
    public delegate int AddHandler(int a, int b);
    public class Calc
    {
        public static int Add(int a, int b)
        {
            Console.WriteLine("Start calculation:" + a + "+" + b);
            Thread.Sleep(3000); //Simulate this method to run for three seconds
            Console.WriteLine("Calculation complete!");
            return a + b;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
         Console.WriteLine("===== Asynchronous callback AsyncInvokeTest =====");
            AddHandler handler2 = new AddHandler(Calc.Add);
            //Asynchronous operation interface(be careful BeginInvoke Different methods!)
            IAsyncResult result2 = handler2.BeginInvoke(1, 2, new AsyncCallback(MyCallBack),
                "AsycState:OK");
            Console.WriteLine("Continue to do other things...");
            Console.ReadKey();
        }    
        static void MyCallBack(IAsyncResult result)
        {
            //result It's an addition class.Add()Return value of method
            //AsyncResult yes IAsyncResult An implementation class of the interface, space: System.Runtime.Remoting.Messaging
            //AsyncDelegate Property 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);
        }      
    }
}


If the type of the delegate is addhandler, then in order to access AddHandler.EndInvoke ,

result is "add" calc.Add Return value of () method

AsyncResult is an implementation class of IAsyncResult interface. Space: System.Runtime.Remoting.Messaging

Asynchronous delegates must be cast to addhandler. Can be invoked in the asynchronous callback function (type AsyncCallback). AddHandler.EndInvoke To get the initial submitted AddHandler.BeginInvoke Results.

 

ok, the sharing of three kinds of delegation calls is here. If you have any questions, please correct!

Posted on Fri, 05 Jun 2020 03:01:33 -0400 by Indersingh