asynchronous invocation and asynchronous design pattern in C # (iii)--event-based Asynchronous Pattern

Source: Internet
Author: User

Iv. event-based Asynchronous Pattern (design level)

The event-based C # Asynchronous Programming pattern is a more advanced asynchronous programming model than the IAsyncResult pattern, and is also used in more contexts. This asynchronous pattern has the following advantages:

· "In the background" performs time-consuming tasks such as downloads and database operations, but does not interrupt your application.

· Multiple operations are performed at the same time, and each operation is notified when it is completed (which can be distinguished by what action is completed in the notification).

· Wait for the resource to become available, but not stop ("suspend") your application.

· Communicates with a pending asynchronous operation using a familiar event and delegate model.

For relatively simple applications that can be conveniently implemented directly with the new BackgroundWorker component of. Net 2.0, For more complex asynchronous applications, you need to implement a class that conforms to the Event-based C # Asynchronous programming pattern. Before implementing the design of an event-based asynchronous pattern, it is necessary to understand what the implementation principle of the event-based asynchronous pattern is. The event-based asynchronous Pattern requires the following three types of help.

asyncoperation: Provides the ability to track the lifetime of an asynchronous operation, including operational progress notifications and operation completion notifications, and ensures that the client's event handlers are invoked in the correct thread or context.

public void Post (SendOrPostCallback d,object Arg);

public void postoperationcompleted (SendOrPostCallback d,object Arg);

Reports progress and intermediate results to the user by calling the Post method in asynchronous secondary code, ending the tracking lifetime of the asynchronous operation by calling the Postoperationcompleted method if the asynchronous task is canceled or the asynchronous task is prompted to complete. After the Postoperationcompleted method call, the AsyncOperation object becomes no longer available, and access again throws an exception. Here's the question: in this asynchronous pattern, how to make the SendOrPostCallback delegate execute on the UI thread when the progress is notified by the AsyncOperation post function. specific analysis is given below for this issue.

AsyncOperationManager: Provides a convenient way to create a AsyncOperation object by CreateOperation method to create multiple asyncoperation instances. Implements tracking multiple asynchronous operations.

WindowsFormsSynchronizationContext: This class inherits from the SynchronizationContext type, providing a synchronization context for the Windows forms application model. This type is the core of the event-based asynchronous mode communication. This type is the core of the communication based on the event asynchronous Pattern because the type resolves the issue of " guaranteed SendOrPostCallback delegate execution on the UI thread ." How it is resolved. See the implementation of the AsyncOperation type Post method:

        <summary>
           Implementation of the///AsyncOperation type Post method
           ///</summary> public
        void Post ( SendOrPostCallback D, object arg)
        {this
            . Verifynotcompleted ();
            This. Verifydelegatenotnull (d);
            This.syncContext.Post (d, Arg);
        }


In the AsyncOperation type of post method, the Post method of the SynchronizationContext type is called directly, and then the implementation of the Post method is seen:

        <summary>
           ///Implementation of POST method for WindowsFormsSynchronizationContext type
           ///</summary>
        Public override void Post (SendOrPostCallback D, object state)
        {
            if (this.controltosendto!= null)
            {
                This.controlToSendTo.BeginInvoke (d, new object[] {state}); This ensures that the SendOrPostCallback delegate executes on the UI thread

            }
        


With the above three types (Asyncopertion,asyncoperationmanager and SynchronizationContext) as the basis, the implementation of the event-based Asynchronous Pattern of progress notification and completion of notifications is much easier. Here's an example of an event-based asynchronous model to end this article.

Using System;
Using System.Collections.Generic;
Using System.Text;
Using System.ComponentModel;
Using System.Collections.Specialized;

Using System.Threading; Namespace Test {///<summary>///Task 1 Progress Notification Agent///</summary>///<param name= "Sender" &GT;&L  t;/param>///<param name= "E" ></param> public delegate void Work1progresschangedeventhandler (object
    sender, Work1progresschangedeventargs e); <summary>///Task 1 Progress notification Parameters///</summary>///<param name= "Sender" ></param>/// <param name= "E" ></param> public delegate void Work1completedeventhandler (object sender, Work1completedeve

    Ntargs e); public class Basedeventasyncworker {private delegate void Workereventhandler (int maxnumber, asyncoperation as
        YNCOP);

        Private HybridDictionary userstatetolifetime = new HybridDictionary (); Public Basedeventasyncworker () {} #region DoWork1 event-basedAsynchronously invokes the public void Dowork1async (object userState, int maxnumber) {AsyncOperation Asyncop = Asyn

            Coperationmanager.createoperation (userState);
                Userstatetolifetime is likely to be accessed simultaneously by multithreading, where lock is required for synchronous processing lock (Userstatetolifetime.syncroot) {
                        if (Userstatetolifetime.contains (userState)) {throw new ArgumentException (
                "UserState parameter must be unique", "userState");
            } Userstatetolifetime[userstate] = Asyncop;
            ///Asynchronous Start Task 1 Workereventhandler workerdelegate = new Workereventhandler (DOWORK1);
        Workerdelegate.begininvoke (MaxNumber, ASYNCOP, NULL, NULL);

            } private void DoWork1 (int maxnumber, asyncoperation asyncop) {Exception e = null; The task of determining the userstate is still in process if (! Taskcanceled (Asyncop.usersuppliedstate){try {int n = 0;
                    int percentage = 0; while (n < maxnumber &&!
                        Taskcanceled (asyncop.usersuppliedstate)) {thread.sleep (100);//Simulate time-consuming operations
                        Percentage = (int) ((float) n/(float) maxnumber * 100); Work1progresschangedeventargs Progresschanageargs = new Work1progresschangedeventargs (MaxNumbe
                        R, percentage, asyncop.usersuppliedstate); 
                        Task 1 Progress Notice asyncop.post (new SendOrPostCallback (WORK1REPORTPROGRESSCB), Progresschanageargs);
                    n++;
                The catch (Exception ex) {e = ex; }} this.
        Work1complete (E, taskcanceled (asyncop.usersuppliedstate), ASYNCOP); } Private void Work1complete (Exception Exception, BOOL canceled, AsyncOperation Asyncop) {if (!canceled) {Lock (userstatetolifetime.syncroot) {USERSTATETOLIFETIME.R
                Emove (asyncop.usersuppliedstate); } Work1completedeventargs e = new Work1completedeventargs (exception, canceled, Asyncop.usersupp

            Liedstate);

            Notifies that the specified task has been completed asyncop.postoperationcompleted (new SendOrPostCallback (WORK1COMPLETECB), E);
            Call the Postoperationcompleted method to end the lifetime of an asynchronous operation.
        Calling this method on a particular task, and then calling its corresponding AsyncOperation object, throws an exception. private void Work1reportprogresscb (object state) {Work1progresschangedeventargs E = state

            As Work1progresschangedeventargs;
        Onwork1progresschanged (e); private void Work1completecb (object state) {Work1completedeventargs E = state as Work1comp LetedevEntargs;
        Onwork1completed (e);
        #region WORK1 Progress Notification and task-completed events public event Work1progresschangedeventhandler work1progresschanged; protected virtual void onwork1progresschanged (Work1progresschangedeventargs e) {work1progresschanged EventHandler temp = this.
            work1progresschanged;
            if (temp!= null) {temp (this, e);
        } public event Work1completedeventhandler work1completed;  protected virtual void onwork1completed (Work1completedeventargs e) {Work1completedeventhandler temp = This.
            work1completed;
            if (temp!= null) {temp (this, e); #endregion #endregion///<summary>///to cancel the task execution of the specified userstate/ /</summary>///<param name= "userState" ></param> public void CancelAsync (object Usersta
        Te{AsyncOperation Asyncop = userstatetolifetime[userstate] as asyncoperation;
                    if (Asyncop!= null) {lock (userstatetolifetime.syncroot) {
                Userstatetolifetime.remove (userState); }}///<summary>///to determine whether the specified userstate task has been terminated. Return value: True has ended; false has not yet ended///</summary>///<param name= "userState" ></param>/ <returns></returns> private bool Taskcanceled (object userState) {return (UserS
        Tatetolifetime[userstate] = = null); } public class Work1progresschangedeventargs:P Rogresschangedeventargs {private int totalwork =

        1; Public Work1progresschangedeventargs (int totalwork, int progresspercentage, Object userState): Base (PROGRESSP
        Ercentage, userState) {this.totalwork = TotalWork;

 }       <summary>///Work1 Total work///</summary> public int TotalWork {
            get {return totalwork; }} public class Work1completedeventargs:asynccompletedeventargs {public Work1completede
 Ventargs (Exception E, BOOL canceled, object state): Base (E, Canceled, state) {}}


 

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.