fork download
  1. public class Program
  2. {
  3. public static void Main(string[] args)
  4. {
  5. Program A = new Program();
  6.  
  7. var oldR = new WeakReference(new ReceiverOld(A));
  8. var newR = new WeakReference(new ReceiverNew(A));
  9.  
  10. A.RaiseTestEvent(); //First
  11.  
  12. //Exec GC
  13. GC.Collect();
  14. GC.WaitForPendingFinalizers();
  15. GC.Collect();
  16.  
  17. A.RaiseTestEvent(); //Second
  18.  
  19. //--Result --
  20. //
  21. // ReceiverOld Received !
  22. // ReceiverNew Received !
  23. // ReceiverOld Received !
  24. //
  25.  
  26. Console.ReadLine();
  27. }
  28.  
  29. private void RaiseTestEvent()
  30. {
  31. var handler = TestEvent;
  32. if (handler != null)
  33. {
  34. handler(this, new RoutedEventArgs());
  35. }
  36. }
  37.  
  38. public event RoutedEventHandler TestEvent;
  39. }
  40.  
  41. //Normal Event Receiver Class
  42. public class ReceiverOld
  43. {
  44. public ReceiverOld(Program b)
  45. {
  46. b.TestEvent += OnTestEvent;
  47. }
  48.  
  49. void OnTestEvent(object sender, RoutedEventArgs e)
  50. {
  51. Console.WriteLine("ReceiverOld Received ! ");
  52. }
  53. }
  54.  
  55. //Event Receiver Class With LivetWeakEventListener
  56. public class ReceiverNew
  57. {
  58. LivetWeakEventListener _listener;//strong reference of listener
  59.  
  60. public ReceiverNew(Program b)
  61. {
  62. _listener = new LivetWeakEventListener(
  63. h => new RoutedEventHandler(h),//h is EventHandler
  64. h => b.TestEvent += h, //h is RoutedEventHandler
  65. h => b.TestEvent -= h, //h is RoutedEventHandler
  66. OnTestEvent);
  67. }
  68.  
  69. void OnTestEvent(object sender, System.Windows.RoutedEventArgs e)
  70. {
  71. Console.WriteLine("ReceiverNew Received ! ");
  72. }
  73. }
  74.  
  75. public class LivetWeakEventListener<THandler, TEventArgs> : IDisposable where TEventArgs : EventArgs
  76. {
  77. private bool _disposed = false;
  78.  
  79. private EventHandler<TEventArgs> _handler;
  80. private THandler _resultHandler;
  81. private Action<THandler> _remove;
  82.  
  83. private static void ReceiveEvent(WeakReference listenerWeakReference, object sender, TEventArgs args)
  84. {
  85. var listener = listenerWeakReference.Target as LivetWeakEventListener<THandler, TEventArgs>;
  86.  
  87. if (listener != null)
  88. {
  89. var handler = listener._handler;
  90.  
  91. if (handler != null)
  92. {
  93. handler(sender, args);
  94. }
  95. }
  96. }
  97.  
  98. private static THandler GetStaticHandler(WeakReference listenerWeakReference, Func<EventHandler<TEventArgs>, THandler> conversion)
  99. {
  100. return conversion((sender, e) => ReceiveEvent(listenerWeakReference, sender, e));
  101. }
  102.  
  103.  
  104. public LivetWeakEventListener(Func<EventHandler<TEventArgs>, THandler> conversion, Action<THandler> add, Action<THandler> remove, EventHandler<TEventArgs> handler)
  105. {
  106. if (conversion == null) throw new ArgumentNullException("conversion");
  107. if (add == null) throw new ArgumentNullException("add");
  108. if (remove == null) throw new ArgumentNullException("remove");
  109. if (handler == null) throw new ArgumentNullException("handler");
  110.  
  111. _handler = handler;
  112. _remove = remove;
  113.  
  114. _resultHandler = GetStaticHandler(new WeakReference(this), conversion);
  115.  
  116. add(_resultHandler);
  117. }
  118.  
  119. public void Dispose()
  120. {
  121. Dispose(true);
  122. GC.SuppressFinalize(this);
  123. }
  124.  
  125. protected virtual void Dispose(bool disposing)
  126. {
  127. if (_disposed) return;
  128.  
  129. if (disposing)
  130. {
  131. _remove(_resultHandler);
  132. }
  133. _disposed = true;
  134. }
  135. }
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty