<hr color="#000000"><br>Multicasting Delegating
Multicasting Delegating
Multicasting היא
תכונה,
שמאפשרת ל-delegate
להצביע על
יותר ממתודה
אחת בו זמנית.
האופרטור =+
מוסיף מתודות
למופע של delegate ,
האופרטור =-
מסיר מתודות
למופע של delegate. כל delegate
יורש ממחלקה
בשם Delegate
והאופרטורים
=+ ו =- יתרגמו
בסופו של דבר
ברמת ה-IL
למתודות Delegate.Combine() ו Delegate.Remove().
הפעלה של delegate Multicast
מבצעת למעשה
הפעלה של
המתודות אחת
אחרי השניה
ע"פ הסדר שהם
נרשמו ל- delegate Multicast. אם
ברצוננו
לשלוט בסדר
הפעלת
המתודות
אנחנו צריכים להפעיל
את המתודה GetInvocationList שמחזירה
מערך של Delegate ואז
באופן יזום
אנחנו יכולים
להפעיל את
המתודות ע"פ
הסדר שאנחנו
רוצים.
Multicasting תכונה מאוד
שימושית
שמפשטת את
הקוד, אך יש
לזכור כמה
נקודת חשובות
באופן פעולתה
שיש לקחת
בחשבון. היא
מבצעת את
הקריאה
למתודות
שנרשמו אליה
באופן סיכרוני,
עד שמתודה לא
סיימה את
עבודתה היא לא
עוברת למתודה
הבא בתור.
תהליך זה עשוי
ליצור מספר
בעיות:
- אם אחת המתודות זורקת Exception כל המתודות שעוד לא בצעו לא יבוצעו אם לא נטפל בזה באופן יזום.
- רק ערך ההחזרה של המתודה האחרונה ברשימה חוזר אלינו.
- המתודות
הנרשמות
יכולות
לסבול מזמן
תגובה איטי
מאוד אם אחת
המתודות לא
מסיימת את
עבודתה בזמן
סביר.
פתרון לסעיף 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.