<hr color="#000000"><br>Multicasting Delegating

Download the code for this article: EventDemo.zip

Multicasting Delegating

 

Multicasting היא תכונה, שמאפשרת ל-delegate להצביע על יותר ממתודה אחת בו זמנית.  האופרטור =+ מוסיף מתודות למופע של delegate , האופרטור =- מסיר מתודות למופע של delegate. כל delegate יורש ממחלקה בשם Delegate והאופרטורים =+ ו =- יתרגמו בסופו של דבר ברמת ה-IL למתודות Delegate.Combine() ו Delegate.Remove().

 

הפעלה של delegate Multicast מבצעת למעשה הפעלה של המתודות אחת אחרי השניה ע"פ הסדר שהם נרשמו ל- delegate Multicast. אם ברצוננו לשלוט בסדר הפעלת המתודות אנחנו צריכים להפעיל את המתודה GetInvocationList שמחזירה מערך של Delegate ואז באופן יזום אנחנו יכולים להפעיל את המתודות ע"פ הסדר שאנחנו רוצים.

 

Multicasting  תכונה מאוד שימושית שמפשטת את הקוד, אך יש לזכור כמה נקודת חשובות באופן פעולתה שיש לקחת בחשבון. היא מבצעת את הקריאה למתודות שנרשמו אליה באופן סיכרוני, עד שמתודה לא סיימה את עבודתה היא לא עוברת למתודה הבא בתור. תהליך זה עשוי ליצור מספר בעיות:

 

  1. אם אחת המתודות זורקת Exception כל המתודות שעוד לא בצעו לא יבוצעו אם לא נטפל בזה באופן יזום.
  2. רק ערך ההחזרה של המתודה האחרונה ברשימה חוזר אלינו.
  3. המתודות הנרשמות יכולות לסבול מזמן תגובה איטי מאוד אם אחת המתודות לא מסיימת את עבודתה בזמן סביר.

 

 

 

פתרון לסעיף 1-2:

 

public delegate bool DemoEventHandler(object sender, EventArgs e);

public event DemoEventHandler StartEvent;

 

 

private void StartEvent_Click(object sender, System.EventArgs e)

{

   if( StartEvent != null ){

       foreach(DemoEventHandler dlg in StartEvent.GetInvocationList()){

          try{         

            if( (bool)dlg.DynamicInvoke(new object[]{this,e}) ){

                  ביצוע המתודה הסתיים בהצלחה......

} else

}

                  ביצוע המתודה לא הסתיים בהצלחה......

            {          

          }

          catch( ApplicationException ex ){

            מונע את הפסקת ביצוע שאר המתודות שעדין לא בוצעו...          

          }

      }

   }

}

 


פתרון לסעיף 1-3:

 

public delegate bool DemoEventHandler(object sender, EventArgs e);

public event DemoEventHandler StartEvent;

 

private void StartEvent_Click(object sender, System.EventArgs e)

{

   if( StartEvent != null ){

       foreach(DemoEventHandler dlg in StartEvent.GetInvocationList()){

          try{

            // Invoke Async call         

            dlg.BeginInvoke(this,e,new AsyncCallback(CallBack),null );       

          }

          catch( ApplicationException ex ){

            מונע את הפסקת ביצוע שאר המתודות שעדין לא בוצעו...          

          }

      }

   }

}

 

 

private void CallBack( IAsyncResult ar )

{

      AsyncResult aResult = (AsyncResult)ar;

      DemoEventHandler dlg = (DemoEventHandler)aResult.AsyncDelegate;

 

      // Complete the asynchronous call.

      if( dlg.EndInvoke( ar ) )

            ביצוע המתודה הסתיים בהצלחה......

      else

            ביצוע המתודה לא הסתיים בהצלחה......

}

 

 

 

 

יש לשים לב שזריקת ה- Exceptionמתבצעת ב- Thread אחר ולכן היא לא נתפסת במתודה  StartEvent_Click.

 

 

No Comments