11using MatthiWare . UpdateLib . Logging ;
2+ using MatthiWare . UpdateLib . Threading ;
23using System ;
34using System . Collections . Generic ;
45using System . ComponentModel ;
@@ -20,12 +21,14 @@ public abstract class AsyncTask
2021 private bool m_useSyncContext = true ;
2122 private SynchronizationContext m_syncContext ;
2223
24+ public bool IsChildTask { get ; internal set ; } = false ;
25+
2326#if DEBUG
2427 public Stopwatch m_sw = new Stopwatch ( ) ;
2528#endif
2629
27- private readonly Queue < WaitHandle > waitQueue = new Queue < WaitHandle > ( ) ;
28- private WaitHandle mainWait ;
30+ private readonly ConcurrentQueue < AsyncTask > m_childTasks = new ConcurrentQueue < AsyncTask > ( ) ;
31+ private ManualResetEvent m_waitHandle = new ManualResetEvent ( true ) ;
2932 private readonly object sync = new object ( ) ;
3033
3134 private bool m_running = false ;
@@ -165,8 +168,8 @@ private void Reset()
165168 LastException = null ;
166169 IsCompleted = false ;
167170
168- mainWait = null ;
169- waitQueue . Clear ( ) ;
171+ m_waitHandle . Reset ( ) ;
172+ m_childTasks . Clear ( ) ;
170173
171174#if DEBUG
172175 m_sw . Reset ( ) ;
@@ -211,7 +214,7 @@ public AsyncTask Start()
211214 m_sw . Start ( ) ;
212215#endif
213216
214- mainWait = worker . BeginInvoke ( new AsyncCallback ( ( IAsyncResult r ) =>
217+ worker . BeginInvoke ( new AsyncCallback ( ( IAsyncResult r ) =>
215218 {
216219#if DEBUG
217220 m_sw . Stop ( ) ;
@@ -221,7 +224,9 @@ public AsyncTask Start()
221224
222225 OnTaskCompleted ( m_lastException , IsCancelled ) ;
223226
224- } ) , null ) . AsyncWaitHandle ;
227+ m_waitHandle . Set ( ) ;
228+
229+ } ) , null ) ; ;
225230
226231 return this ;
227232 }
@@ -247,27 +252,25 @@ public virtual void Cancel()
247252 /// <param name="args">Optional arguments for the action</param>
248253 protected void Enqueue ( Delegate action , params object [ ] args )
249254 {
250- Action subTaskAction = new Action ( ( ) =>
255+ // Don't allow to start another task when the parent task has been cancelled or contains errors.
256+ if ( HasErrors || IsCancelled )
257+ return ;
258+
259+ AsyncTask task = AsyncTaskFactory . From ( action , args ) ;
260+ task . IsChildTask = true ;
261+ task . TaskCompleted += ( o , e ) =>
251262 {
252- try
263+ if ( e . Error != null )
253264 {
254- action . DynamicInvoke ( args ) ;
255- }
256- catch ( Exception ex )
257- {
258- LastException = ex ? . InnerException ?? ex ;
265+ LastException = e . Error ? . InnerException ?? e . Error ;
259266
260267 Logger . Error ( GetType ( ) . Name , LastException ) ;
261268 }
262- } ) ;
269+ } ;
263270
264- // Don't allow to start another task when the parent task has been cancelled or contains errors.
265- if ( HasErrors || IsCancelled )
266- return ;
271+ m_childTasks . Enqueue ( task ) ;
267272
268- IAsyncResult result = subTaskAction . BeginInvoke ( new AsyncCallback ( r => { subTaskAction . EndInvoke ( r ) ; } ) , null ) ;
269- lock ( sync )
270- waitQueue . Enqueue ( result . AsyncWaitHandle ) ;
273+ WorkerScheduler . Instance . Schedule ( task ) ;
271274 }
272275
273276 /// <summary>
@@ -276,28 +279,27 @@ protected void Enqueue(Delegate action, params object[] args)
276279 /// </summary>
277280 public void AwaitTask ( )
278281 {
279- if ( mainWait != null )
282+ if ( IsChildTask && ! IsCompleted && ! IsRunning )
283+ Reset ( ) ;
284+
285+ if ( m_waitHandle != null )
280286 {
281- mainWait . WaitOne ( ) ;
282- mainWait . Close ( ) ;
283- mainWait = null ;
287+ m_waitHandle . WaitOne ( ) ;
288+ m_waitHandle . Close ( ) ;
289+ m_waitHandle = null ;
284290 }
285291 }
286292
293+ private int x = 0 ;
294+
287295 /// <summary>
288296 /// Blocks the calling thread until all the workers are done.
289297 /// </summary>
290298 protected void AwaitWorkers ( )
291299 {
292- while ( waitQueue . Count > 0 )
293- {
294- WaitHandle wh = null ;
295- lock ( sync )
296- wh = waitQueue . Dequeue ( ) ;
297-
298- wh . WaitOne ( ) ;
299- wh . Close ( ) ;
300- }
300+ AsyncTask task = null ;
301+ while ( m_childTasks . TryDequeue ( out task ) )
302+ task . AwaitTask ( ) ;
301303 }
302304
303305 /// <summary>
0 commit comments