comparison Util/AsyncResultBase.cs @ 18:a6faa87767bb

AsyncResultBase: prevent recursive synchronous completion callback
author Ivo Smits <Ivo@UCIS.nl>
date Wed, 10 Apr 2013 01:33:54 +0200
parents 4b78cc5f116b
children 327be9216006
comparison
equal deleted inserted replaced
17:5d9a7186c9f7 18:a6faa87767bb
2 using System.Threading; 2 using System.Threading;
3 using SysThreadPool = System.Threading.ThreadPool; 3 using SysThreadPool = System.Threading.ThreadPool;
4 4
5 namespace UCIS.Util { 5 namespace UCIS.Util {
6 public abstract class AsyncResultBase : IAsyncResult { 6 public abstract class AsyncResultBase : IAsyncResult {
7 [ThreadStatic]
8 static Boolean ThreadInCallback = false;
7 ManualResetEvent WaitEvent = null; 9 ManualResetEvent WaitEvent = null;
8 AsyncCallback Callback = null; 10 AsyncCallback Callback = null;
9 public object AsyncState { get; private set; } 11 public object AsyncState { get; private set; }
10 public bool CompletedSynchronously { get; private set; } 12 public bool CompletedSynchronously { get; private set; }
11 public bool IsCompleted { get; private set; } 13 public bool IsCompleted { get; private set; }
34 lock (this) { 36 lock (this) {
35 IsCompleted = true; 37 IsCompleted = true;
36 if (WaitEvent != null) WaitEvent.Set(); 38 if (WaitEvent != null) WaitEvent.Set();
37 } 39 }
38 if (Callback != null) { 40 if (Callback != null) {
39 if (synchronously) { 41 if (synchronously && !ThreadInCallback) {
40 Callback(this); 42 try {
43 ThreadInCallback = true;
44 Callback(this);
45 } finally {
46 ThreadInCallback = false;
47 }
41 } else { 48 } else {
42 SysThreadPool.QueueUserWorkItem(CallCallback); 49 SysThreadPool.QueueUserWorkItem(CallCallback);
43 } 50 }
44 } 51 }
45 } 52 }