Article From:https://www.cnblogs.com/zhlziliaoku/p/9217170.html

Asynchronous programming can avoid occupancy of threads while waiting for a task to complete, but it is still very troublesome to realize programming correctly.

. NET Framework There are three different models to simplify asynchronous programming.

    .NET 1. x The BeginFoo/ EndFoo method is used to propagate the results using IAsyncResult and AsyncCallback.

    .NET 2. 0 Event based asynchronous mode is implemented using BackgroundWorker and WebClient.

    .NET 4 The task parallel library (TPL) is expanded and expanded by. NET 4.5.

(1) APM (asynchronous programming model) C# version is 1.1

   APMThe most typical feature of asynchronous programming model is that an asynchronous function consists of two methods, which start with Begin and start with End. The method at the beginning of Begin indicates the execution of the start asynchronous function. The method at the beginning of End indicates that the execution of the asynchronous function ends and the execution result is returned.

  Simulation Implementation:

public class Worker
    {
        public int A { get; set; }
        public int B { get; set; }
        private int R { get; set; }
        ManualResetEvent et;
        public void BeginWork(Action action)
        {
            et = new ManualResetEvent(false);
            new Thread(() =>
            {
                R = A + B;
                Thread.Sleep(1000);
                et.Set();
                if(null != action)
                {
                    action();
                }
            }).Start();
        }

        public int EndWork()
        {
            if(null == et)
            {
                throw new Exception("Before calling EndWork, you need to call BeginWork first");
            }
            else
            {
                et.WaitOne();
                return R;
            }

        } 
    }

View Code

Call code:

 static void Main(string[] args)
        {
           Worker w = new Worker();
            w.BeginWork(()=> {
                Console.WriteLine("Thread Id:{0},Count:{1}", Thread.CurrentThread.ManagedThreadId,
                    w.EndWork());
            });
            Console.WriteLine("Thread Id:{0}", Thread.CurrentThread.ManagedThreadId);
            Console.ReadLine();
        }

View Code

How does the standard APM model implement asynchronous programming:

IAsyncResultInterface

IAsyncResultThe interface defines the state of the asynchronous function. The specific properties and meanings of the interface are as follows:

 //     The state of an asynchronous operation.
    [ComVisible(true)]
    public interface IAsyncResult
    {
        //
        // Abstract://     Gets a value indicating whether the asynchronous operation has been completed.//
        // Return to the result://     If the operation is completed, it is true; otherwise, it is false.
        bool IsCompleted { get; }
        //
        // Abstract://     Gets the System.Threading.WaitHandle used to wait for the asynchronous operation to complete.//
        // Return to the result://     System.Threading.WaitHandle for waiting for asynchronous operation to complete.
        WaitHandle AsyncWaitHandle { get; }
        //
        // Abstract://     Gets a user defined object that defines or contains information about asynchronous operations.//
        // Return to the result://     A user defined object that defines or contains information about asynchronous operations.
        object AsyncState { get; }
        //
        // Abstract://     Gets a value indicating whether the asynchronous operation is completed synchronously.//
        // Return to the result://     If the asynchronous operation is completed synchronously, it is true; otherwise, it is false.
        bool CompletedSynchronously { get; }
    }

View Code

Implementation of the interface:

public class NewWorker
    {
        public class WorkerAsyncResult : IAsyncResult
        {
            AsyncCallback callback;
            public WorkerAsyncResult(int a,int b, AsyncCallback callback, object asyncState) {
                A = a;
                B = b;
                state = asyncState;
                this.callback = callback;
                new Thread(Count).Start(this);
            }
            public int A { get; set; }
            public int B { get; set; }

            public int R { get; private set; }

            private object state;
            public object AsyncState
            {
                get
                {
                    return state;
                }
            }
            private ManualResetEvent waitHandle;
            public WaitHandle AsyncWaitHandle
            {
                get
                {
                    if (null == waitHandle)
                    {
                        waitHandle = new ManualResetEvent(false);
                    }
                    return waitHandle;
                }
            }
            private bool completedSynchronously;
            public bool CompletedSynchronously
            {
                get
                {
                    return completedSynchronously;
                }
            }
            private bool isCompleted;
            public bool IsCompleted
            {
                get
                {
                    return isCompleted;
                }
            }
            private static void Count(object state)
            {
                var result = state as WorkerAsyncResult;
                result.R = result.A + result.B;
                Thread.Sleep(1000);
                result.completedSynchronously = false;
                result.isCompleted = true;
                ((ManualResetEvent)result.AsyncWaitHandle).Set();
                if (result.callback != null)
                {
                    result.callback(result);
                }
            }
        }
        public int Num1 { get; set; }
        public int Num2 { get; set; }

        public IAsyncResult BeginWork(AsyncCallback userCallback, object asyncState)
        {
            IAsyncResult result = new WorkerAsyncResult(Num1,Num2,userCallback, asyncState);
            return result;
        }

        public int EndWork(IAsyncResult result)
        {
            WorkerAsyncResult r = result as WorkerAsyncResult;
            r.AsyncWaitHandle.WaitOne();
            return r.R;
        }
    }

View Code

Call:

static void Main(string[] args)
        {
            NewWorker w2 = new NewWorker();
            w2.Num1 = 10;
            w2.Num2 = 12;
            IAsyncResult r = null;
            r = w2.BeginWork((obj) => {
            Console.WriteLine("Thread Id:{0},Count:{1}",Thread.CurrentThread.ManagedThreadId,
            w2.EndWork(r));
            }, null);
            Console.WriteLine("Thread Id:{0}", Thread.CurrentThread.ManagedThreadId);
            Console.ReadLine();
        }

View Code

DelegateAsynchronous programming (APM Standard Implementation)

public class NewWorker2
    {
        Func<int, int, int> action;
        public NewWorker2()
        {
            action = new Func<int, int, int>(Work);
        }
        public IAsyncResult BeginWork(AsyncCallback callback, object state)
        {
            dynamic obj = state;
            return action.BeginInvoke(obj.A, obj.B, callback, this);
        }

        public int EndWork(IAsyncResult asyncResult)
        {
            try
            {
                return action.EndInvoke(asyncResult);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private int Work(int a, int b)
        {
            Thread.Sleep(1000);
            return a + b;
        }
    }

View Code

 static void Main(string[] args)
        {
            NewWorker2 w2 = new NewWorker2();
            IAsyncResult r = null;
            r = w2.BeginWork((obj) =>
            {
                Console.WriteLine("Thread Id:{0},Count:{1}", Thread.CurrentThread.ManagedThreadId,
                    w2.EndWork(r));
            }, new { A = 10, B = 11 });
            Console.WriteLine("Thread Id:{0}", Thread.CurrentThread.ManagedThreadId);

            Console.ReadLine();
        }

View Code

 Learning website: https://blog.csdn.net/nginxs/article/details/77917172

Leave a Reply

Your email address will not be published. Required fields are marked *