@@ -14,15 +14,21 @@ public class CollectArgs : EventArgs
1414 public int ObjectCount { get ; set ; }
1515 }
1616
17+ public class ErrorArgs : EventArgs
18+ {
19+ public Exception Error { get ; set ; }
20+ }
21+
1722 public static readonly Finalizer Instance = new Finalizer ( ) ;
1823
1924 public event EventHandler < CollectArgs > CollectOnce ;
25+ public event EventHandler < ErrorArgs > ErrorHandler ;
2026
2127 private ConcurrentQueue < IDisposable > _objQueue = new ConcurrentQueue < IDisposable > ( ) ;
2228
2329 [ UnmanagedFunctionPointer ( CallingConvention . Cdecl ) ]
24- private delegate int PedingCall ( IntPtr arg ) ;
25- private readonly PedingCall _collectAction ;
30+ private delegate int PendingCall ( IntPtr arg ) ;
31+ private readonly PendingCall _collectAction ;
2632
2733 private bool _pending = false ;
2834 private readonly object _collectingLock = new object ( ) ;
@@ -87,24 +93,27 @@ internal static void Shutdown()
8793 }
8894 Instance . DisposeAll ( ) ;
8995 Instance . CallPendingFinalizers ( ) ;
90- Runtime . PyErr_Clear ( ) ;
9196 }
9297
9398 private void AddPendingCollect ( )
9499 {
100+ if ( _pending )
101+ {
102+ return ;
103+ }
95104 lock ( _collectingLock )
96105 {
97106 if ( _pending )
98107 {
99108 return ;
100109 }
101110 _pending = true ;
102- }
103- IntPtr func = Marshal . GetFunctionPointerForDelegate ( _collectAction ) ;
104- if ( Runtime . Py_AddPendingCall ( func , IntPtr . Zero ) != 0 )
105- {
106- // Full queue, append next time
107- _pending = false ;
111+ IntPtr func = Marshal . GetFunctionPointerForDelegate ( _collectAction ) ;
112+ if ( Runtime . Py_AddPendingCall ( func , IntPtr . Zero ) != 0 )
113+ {
114+ // Full queue, append next time
115+ _pending = false ;
116+ }
108117 }
109118 }
110119
@@ -124,7 +133,19 @@ private void DisposeAll()
124133 IDisposable obj ;
125134 while ( _objQueue . TryDequeue ( out obj ) )
126135 {
127- obj . Dispose ( ) ;
136+ try
137+ {
138+ obj . Dispose ( ) ;
139+ Runtime . CheckExceptionOccurred ( ) ;
140+ }
141+ catch ( Exception e )
142+ {
143+ // We should not bother the main thread
144+ ErrorHandler ? . Invoke ( this , new ErrorArgs ( )
145+ {
146+ Error = e
147+ } ) ;
148+ }
128149 }
129150 }
130151 }
0 commit comments