207. Solving the problem with events - part 6

אמרתי פעם שעברה שאני אראה כיצד אפשר להסיר באופן ייזום Weak event שנרשם לאירוע שלנו.

ובכן, כדי לעשות זאת נצטרך להוסיף PropertyלWeakEventHandler:

1
2
3
4
5
6
7
public MethodInfo Method
{
get
{
return mHandlerMethodInfo;
}
}

האנלוגי לProperty בשם Method שיש לDelegate כלשהו.

כעת בפונקצית הסרת הרישום נעשה משהו כזה:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public event EventHandler<EventArgs> EventRaised
{
add
{
mEventRaised += value.MakeWeak(x => mEventRaised -= x);
}
remove
{
Delegate[] subscribers = mEventRaised.GetInvocationList();
IEnumerable<WeakEventHandler<EventArgs>> weakSubscribers =
subscribers.Select(x => x.Target).OfType<WeakEventHandler<EventArgs>>();
IEnumerable<WeakEventHandler<EventArgs>> requestedSubscribers =
weakSubscribers.Where(x => (x.Method == value.Method) &&
(x.Target == value.Target));
WeakEventHandler<EventArgs> requestedSubscriber =
requestedSubscribers.FirstOrDefault();
if (requestedSubscriber != null)
{
mEventRaised -= requestedSubscriber.Invoke;
}
}
}

אנחנו בעצם מחפשים את כל הרשומים לפונקציה שהם WeakEventHandler עם Method וTarget שמתאימים לזה שאנחנו קיבלנו. (אם קיבלנו Reference לTarget כלשהו, זה אומר שהTarget עדיין בחיים ולכן הWeak Reference לא היה אמור למות)

לאחר מכן אנחנו מוצאים את הראשון ומסירים את הרישום שלו מהDelegate.

אפשר כמובן להפוך את זה לExtension Method שיהיה אפשר להשתמש בו גם למקרים שבהם הפרמטר הגנרי הוא לא EventArgs אלא משהו אחר.


נראה לי שהסדרה הזאת מסתיימת כאן, אלא אם כן אני אחשוב על עוד משהו לכתוב.

אני רוצה לציין שהסדרה מבוססת על הפוסט Solving the Problem with Events: Weak Event Handlers מהבלוג DidItWithNet. יש הבדלים בין הדרכים שהצגתי לדרכים שהוא מציג שם, משום שמהבדיקות שעשיתי ראיתי שהוא לא ממש צודק, ולכן לא נכנסתי לכל מיני דברים כמו unbound delegates. אתם מוזמנים לקרוא את הפוסט הזה, הוא די טוב.

המשך יום מלא אירועים בלי שום דליפות טוב.

שתף