@@ -15,6 +15,66 @@ namespace System.Reactive
1515    /// <typeparam name="TEventArgs">The type of the event data generated by the event.</typeparam> 
1616    public  abstract  class  EventPatternSourceBase < TSender ,  TEventArgs > 
1717    { 
18+         private  sealed  class  Observer  :  ObserverBase < EventPattern < TSender ,  TEventArgs > > ,  ISafeObserver < EventPattern < TSender ,  TEventArgs > > 
19+         { 
20+             private  bool  _isDone ; 
21+             private  bool  _isAdded ; 
22+             private  readonly  Delegate  _handler ; 
23+             private  readonly  object  _gate  =  new  object ( ) ; 
24+             private  readonly  Action < TSender ,  TEventArgs >  _invoke ; 
25+             private  readonly  EventPatternSourceBase < TSender ,  TEventArgs >  _sourceBase ; 
26+ 
27+             public  Observer ( EventPatternSourceBase < TSender ,  TEventArgs >  sourceBase ,  Delegate  handler ,  Action < TSender ,  TEventArgs >  invoke ) 
28+             { 
29+                 _handler  =  handler ; 
30+                 _invoke  =  invoke ; 
31+                 _sourceBase  =  sourceBase ; 
32+             } 
33+ 
34+             protected  override  void  OnNextCore ( EventPattern < TSender ,  TEventArgs >  value ) 
35+             { 
36+                 _sourceBase . _invokeHandler ( _invoke ,  value ) ; 
37+             } 
38+ 
39+             protected  override  void  OnErrorCore ( Exception  error ) 
40+             { 
41+                 Remove ( ) ; 
42+                 error . Throw ( ) ; 
43+             } 
44+ 
45+             protected  override  void  OnCompletedCore ( ) 
46+             { 
47+                 Remove ( ) ; 
48+             } 
49+ 
50+             private  void  Remove ( ) 
51+             { 
52+                 lock  ( _gate ) 
53+                 { 
54+                     if  ( _isAdded ) 
55+                     { 
56+                         _sourceBase . Remove ( _handler ) ; 
57+                     } 
58+                     else 
59+                     { 
60+                         _isDone  =  true ; 
61+                     } 
62+                 } 
63+             } 
64+ 
65+             public  void  SetResource ( IDisposable  resource ) 
66+             { 
67+                 lock  ( _gate ) 
68+                 { 
69+                     if  ( ! _isDone ) 
70+                     { 
71+                         _sourceBase . Add ( _handler ,  resource ) ; 
72+                         _isAdded  =  true ; 
73+                     } 
74+                 } 
75+             } 
76+         } 
77+ 
1878        private  readonly  IObservable < EventPattern < TSender ,  TEventArgs > >  _source ; 
1979        private  readonly  Dictionary < Delegate ,  Stack < IDisposable > >  _subscriptions ; 
2080        private  readonly  Action < Action < TSender ,  TEventArgs > ,  /*object,*/  EventPattern < TSender ,  TEventArgs > >  _invokeHandler ; 
@@ -50,50 +110,18 @@ protected void Add(Delegate handler, Action<TSender, TEventArgs> invoke)
50110                throw  new  ArgumentNullException ( nameof ( invoke ) ) ; 
51111            } 
52112
53-             var  gate  =  new  object ( ) ; 
54-             var  isAdded  =  false ; 
55-             var  isDone  =  false ; 
56- 
57-             var  remove  =  new  Action ( ( )  => 
58-             { 
59-                 lock  ( gate ) 
60-                 { 
61-                     if  ( isAdded ) 
62-                     { 
63-                         Remove ( handler ) ; 
64-                     } 
65-                     else 
66-                     { 
67-                         isDone  =  true ; 
68-                     } 
69-                 } 
70-             } ) ; 
71- 
113+             var  observer  =  new  Observer ( this ,  handler ,  invoke ) ; 
72114            // 
73115            // [OK] Use of unsafe Subscribe: non-pretentious wrapper of an observable in an event; exceptions can occur during +=. 
74116            // 
75-             var  d  =  _source . Subscribe /*Unsafe*/ ( 
76-                 x =>  _invokeHandler ( invoke ,  /*this,*/  x ) , 
77-                 ex =>  {  remove ( ) ;  ex . Throw ( ) ;  } , 
78-                 remove 
79-             ) ; 
80- 
81-             lock  ( gate ) 
82-             { 
83-                 if  ( ! isDone ) 
84-                 { 
85-                     Add ( handler ,  d ) ; 
86-                     isAdded  =  true ; 
87-                 } 
88-             } 
117+             observer . SetResource ( _source . Subscribe ( observer ) ) ; 
89118        } 
90119
91120        private  void  Add ( Delegate  handler ,  IDisposable  disposable ) 
92121        { 
93122            lock  ( _subscriptions ) 
94123            { 
95-                 var  l  =  new  Stack < IDisposable > ( ) ; 
96-                 if  ( ! _subscriptions . TryGetValue ( handler ,  out  l ) ) 
124+                 if  ( ! _subscriptions . TryGetValue ( handler ,  out  var  l ) ) 
97125                { 
98126                    _subscriptions [ handler ]  =  l  =  new  Stack < IDisposable > ( ) ; 
99127                } 
@@ -118,8 +146,7 @@ protected void Remove(Delegate handler)
118146
119147            lock  ( _subscriptions ) 
120148            { 
121-                 var  l  =  new  Stack < IDisposable > ( ) ; 
122-                 if  ( _subscriptions . TryGetValue ( handler ,  out  l ) ) 
149+                 if  ( _subscriptions . TryGetValue ( handler ,  out  var  l ) ) 
123150                { 
124151                    d  =  l . Pop ( ) ; 
125152
0 commit comments