fork(1) download
  1. namespace ConsoleApplication1
  2. {
  3. public class Program
  4. {
  5. public static void Main(string[] args)
  6. {
  7. Program A = new Program();
  8.  
  9. //本来メソッドスコープないの変数はメソッド中に
  10. //回収される事はありませんが、
  11. //WeakReferenceで囲う事でGCで回収可能にします。
  12. var oldR = new WeakReference(new ReceiverOld(A));
  13. var newR = new WeakReference(new ReceiverNew(A));
  14.  
  15. A.RaiseTestEvent();//1回目のイベント呼び出し
  16.  
  17. //ガベージコレクションの実行
  18. GC.Collect();
  19. GC.WaitForPendingFinalizers();
  20. GC.Collect();
  21.  
  22. A.RaiseTestEvent();//2回目のイベント呼び出し
  23.  
  24. //--結果 --
  25. //
  26. // ReceiverOld Received !
  27. // ReceiverNew Received !
  28. // ReceiverOld Received !
  29. //
  30. //2度目のイベント呼び出しではReceiverNewのイベントハンドラが呼び出されていない!
  31. //
  32. //GC後もProgram AがRecieveOldのイベントハンドラを参照しているから、
  33. //oldAオブジェクトはGCに回収されていません。
  34. //
  35. //しかし今回の汎用WeakEventListenerを使ったnewAオブジェクトは見事回収されています。
  36.  
  37. Console.ReadLine();
  38. }
  39.  
  40. private void RaiseTestEvent()
  41. {
  42. var handler = TestEvent;
  43. if (handler != null)
  44. {
  45. handler(this, new RoutedEventArgs());
  46. }
  47. }
  48.  
  49. public event RoutedEventHandler TestEvent;
  50. }
  51.  
  52. //通常通りイベントを受信しているオブジェクト
  53. public class ReceiverOld
  54. {
  55. public ReceiverOld(Program b)
  56. {
  57. b.TestEvent += OnTestEvent;
  58. }
  59.  
  60. void OnTestEvent(object sender, RoutedEventArgs e)
  61. {
  62. Console.WriteLine("ReceiverOld Received ! ");
  63. }
  64. }
  65.  
  66. //今回の汎用WeakEventListener使ってイベントを受信しているオブジェクト
  67. public class ReceiverNew
  68. {
  69. LivetWeakEventListener<RoutedEventHandler, RoutedEventArgs> _listener;//リスナへの強い参照を保持
  70.  
  71. public ReceiverNew(Program b)
  72. {
  73. _listener = new LivetWeakEventListener<RoutedEventHandler, RoutedEventArgs>(
  74. h => new RoutedEventHandler(h),//このhはEventHandler<RoutedEventArgs>
  75. h => b.TestEvent += h,//このhはRoutedEventHandler
  76. h => b.TestEvent -= h,//このhはRoutedEventHandler
  77. OnTestEvent);//本来のハンドラ
  78. }
  79.  
  80. void OnTestEvent(object sender, System.Windows.RoutedEventArgs e)
  81. {
  82. Console.WriteLine("ReceiverNew Received ! ");
  83. }
  84.  
  85.  
  86. }
  87. }
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty