C # Asynchronous APM mode Asynchronous program development sample sharing

Source: Internet
Author: User
Tags apm
C # has more than 10 years of history, single from the Microsoft 2 Edition of the update progress to see the vitality of the unusually vigorous, C # Asynchronous programming has also undergone several versions of the evolution, from today, handwritten a series of blog post, documenting the development of asynchronous programming in C #. Advertising: Like my article friends, please click on the following "Follow me." Thanks

I contacted and used C # in 2004, when the C # version was 1.1, so we talked about it from that moment on. At that time in the University of their own reading and writing programs, the program is written mostly synchronous program, up to start a thread ... In fact, in the c#1.1 era there is a complete asynchronous programming solution, that is APM (asynchronous programming model). If you do not understand the "Synchronizer, asynchronous program," Please Baidu Oh.

The most representative feature of the APM asynchronous programming model is that an asynchronous function consists of two methods beginning with begin and end. The method beginning with begin represents the execution of the initiating asynchronous function, and the method at the beginning of the end indicates waiting for the asynchronous function to finish and return the execution result. Here is an implementation of the simulation (the standard APM model is later written asynchronously):

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) {t hrow new Excepti            On ("Before calling Endwork, you need to call Beginwork first"); } else {et.                                WaitOne ();            return R; }        }     }
        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 ();        }

In the above simulation APM model we used thread, ManualResetEvent, if you are not familiar with multithreading and ManualResetEvent in C # The use of asynchronous programming inevitably involves multithreading knowledge, Although Microsoft has done a lot of packaging in the framework, friends should be in control of their nature.

The above simulation of the APM Async model is simple because the C # development process introduced a lot of good grammar rules. In the example above, we use lambda expressions more, and if you are unfamiliar with anonymous delegates and lambda expressions, see my previous Bolg, "Anonymous delegates and lambda expressions." With so many ads on it, let's take a look at how the standard APM model implements asynchronous programming.

IAsyncResult interface

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

        represents the state of an asynchronous operation.    [ComVisible (true)] public    interface IAsyncResult    {////        Abstract:        //     Gets a value indicating whether the asynchronous operation has completed. ////        Returns the result:        //     True if the operation was completed; otherwise false.        bool iscompleted {get;}        //Summary:        //     Gets the System.Threading.WaitHandle that is used to wait for the asynchronous operation to complete. ////        return Result:        //     System.Threading.WaitHandle to wait for the asynchronous operation to complete.        WaitHandle asyncwaithandle {get;}        //Summary:        //     Gets a user-defined object that qualifies or contains information about the asynchronous operation. ////        Returns the result:        //     a user-defined object that qualifies or contains information about the asynchronous operation.        object asyncstate {get;}        //Summary:        //     Gets a value that indicates whether the asynchronous operation is complete synchronously. ////        Returns the result:        //     True if the asynchronous operation completes synchronously; false otherwise.        bool completedsynchronously {get;}    }

Note: ManualResetEvent in model Example 1 inherits from WaitHandle
APM Legend Realization Way
After understanding the IAsyncResult interface, we can do the work of rewriting the simulation example by implementing the IAsyncResult interface, the code is as follows:

    public class Newworker {public class Workerasyncresult:iasyncresult {AsyncCallback cal                        Lback;                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 {R}                Eturn State;                        }} private ManualResetEvent WaitHandle;   Public WaitHandle AsyncWaitHandle {get             {if (null = = WaitHandle) {wait                    Handle = new ManualResetEvent (false);                } return waitHandle;                        }} private bool completedsynchronously; public bool completedsynchronously {get {ret                Urn completedsynchronously;                        }} private bool iscompleted; public bool IsCompleted {get {RE                Turn 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; }    }

Sample Code Analysis:

The inner class workerasyncresult of Newworker in the above code is the key point, which implements the IAsyncResult interface and is responsible for opening the new thread to complete the calculation work.

A, b Two private properties are added to the Workerasyncresult to store the numeric value used for the calculation, an externally readable, non-writable property R that stores the results of the Workerasyncresult internal operation. The AsyncWaitHandle property is played by ManualResetEvent and created ManualResetEvent (but not freed) on first access. Other interface properties are implemented normally, nothing to say.

The static Count method in Workerasyncresult is added, and the parameter state is the current Workerasyncresult object that calls the Count method. The Count method runs in the city thread of the Workerasyncresult object, so Thread.Sleep (1000) will block the new thread for 1 seconds. The current Workerasyncresult object is then set to false, the asynchronous completion state is true, and the ManualResetEvent notification is released to wait for the thread to get the notification into the execution state, to determine if there is an asynchronous execution end callback delegate, and the callback is present.

Newworker is very simple, Num1, Num2 Two properties are the values to be computed. Beginwork Create a Workerasyncresult object, and the two numeric Num1, Num2, Usercallback callback delegate, object type asyncstate that will be computed Pass in the Workerasyncresult object you want to create. With this step, the Workerasyncresult object obtains all the data required for the operation, the callback after the operation completes, and immediately initiates a new thread to perform the operation (the Workerasyncresult.count method is executed).

Because Workerasyncresult.count executes in a new thread, the state of the new thread cannot be accurately learned outside the thread. To satisfy the need for external threads to synchronize with new threads, add the Endwork method to the Newworker, with the parameter type IAsyncResult. To call the Endwork method, you should pass in the Workerasyncresult object that Beginwork gets, and after the Endwork method gets the Workerasyncresult object, Call the WorkerAsyncResult.AsyncWaitHandle.WaitOne () method, wait for the ManualResetEvent notification to get to the notification when the arithmetic thread has completed the operation (the thread is not finished), and next gets the result of the Operation R and returns.

Next is the Newworker calling program, as follows:

        static void Main (string[] args)        {            Newworker w2 = new Newworker ();            W2. NUM1 = ten;            W2. Num2 = n;            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 ();        }

My simple drawing program calls the process to help your friends understand:

The standard APM model for asynchronous programming is too complex for developers. Therefore, by implementing the IAsyncResult interface for asynchronous programming, it is legendary to see useless (sin sin ...). )。

Delegate asynchronous programming (APM standard implementation)

In C #, delegates naturally support asynchronous calls (APM models), after any delegate object "." You will find BeginInvoke, EndInvoke, invoke three methods. The BeginInvoke invokes the delegate asynchronously, EndInvoke the end of the asynchronous call that waits for the delegate, and invoke synchronously invokes the delegate. As a result, the standard APM example above can be simplified with delegate.

The above Newworker uses the delegate method to rewrite as follows:



    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 (+);            return a + B;        }    }

Calling program:

        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 = ten, B = one});            Console.WriteLine ("Thread id:{0}", Thread.CurrentThread.ManagedThreadId);            Console.ReadLine ();        }

The above uses a delegate for APM asynchronous programming, which is much more streamlined and easier to understand than the way the IAsyncResult interface is implemented. Therefore, it is suggested that friends delegate asynchronous call model should be mastered, and through the implementation of the IAsyncResult interface of the legendary way to see your preferences.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.