I try to solve such a problem: When the delegate is called by user, the response object of delegate
is dead (or out scope). This problem may throw an exception.
WeakReference and GC.Collect() ? Oh,GC is clumsy, WeakReference.IsAlive is not realtime.
my code:
public class Apple { public Apple() { MessageDispatch.Instance.BindingMessage(0, OnMessage); } public void OnMessage(object sender, EventArgs e) { Console.WriteLine("Apple,thanks."); } } public class MessageDispatch { public static readonly MessageDispatch Instance = new MessageDispatch(); Dictionary<int, List<Pack>> _dic = new Dictionary<int, List<Pack>>(); class Pack { public WeakReference WObject; public MethodInfo WEvent; } public void BindingMessage(int msgId, EventHandler e) { if (!_dic.ContainsKey(msgId)) _dic[msgId] = new List<Pack>(); Pack pack = new Pack(); pack.WObject = new WeakReference(e.Target); pack.WEvent = e.Method; _dic[msgId].Add(pack); } public void PostMessage(int msgId, Object sender, EventArgs data) { if (!_dic.ContainsKey(msgId)) return; //GC.Collect(); //so weight。 foreach (Pack p in _dic[msgId]) { if (p.WObject.Target != null) p.WEvent.Invoke(p.WObject.Target, new object[]{sender, data}); } } } Test: private void Test_One() { Apple a1 = new Apple(); CreateTempVal(); MessageDispatch.Instance.PostMessage(0, null, EventArgs.Empty); } private void CreateTempVal() { Apple a2 = new Apple(); }
print:
Apple,thanks.
Apple,thanks.
Used GC.Collect(), print:
Apple,thanks.
Test_One(): a1 is valid, and a2 is invalid. if not using GC.Collect(), a1 and a2 are valid ( in my code).
The MessageDispatch is like windows message principle: Register Message (BindingMessage(msgId, ))
and post message(PostMessage(msgId, )), and then we can reponse message anywhere.
I used GC and WeakReference to solve: outed scope object will not be called. ( void Test_One())
If this:
void OnMouseMove(object sender, EventArgs e) { MessageDispatch.Instance.PostMessage(0, sender,e); }
GC will crazy. What should i do ?
Thanks.