Mercurial > hg > ucis.core
annotate Util/AsyncResultBase.cs @ 111:df53bdd49507 default tip
Merge
author | Ivo Smits <Ivo@UCIS.nl> |
---|---|
date | Fri, 07 Nov 2014 18:37:39 +0100 |
parents | 327be9216006 |
children |
rev | line source |
---|---|
5 | 1 ???using System; |
2 using System.Threading; | |
3 using SysThreadPool = System.Threading.ThreadPool; | |
4 | |
5 namespace UCIS.Util { | |
6 public abstract class AsyncResultBase : IAsyncResult { | |
18
a6faa87767bb
AsyncResultBase: prevent recursive synchronous completion callback
Ivo Smits <Ivo@UCIS.nl>
parents:
7
diff
changeset
|
7 [ThreadStatic] |
a6faa87767bb
AsyncResultBase: prevent recursive synchronous completion callback
Ivo Smits <Ivo@UCIS.nl>
parents:
7
diff
changeset
|
8 static Boolean ThreadInCallback = false; |
5 | 9 ManualResetEvent WaitEvent = null; |
10 AsyncCallback Callback = null; | |
104 | 11 Object MonitorWaitHandle = new Object(); |
5 | 12 public object AsyncState { get; private set; } |
13 public bool CompletedSynchronously { get; private set; } | |
14 public bool IsCompleted { get; private set; } | |
15 public Exception Error { get; private set; } | |
16 public WaitHandle AsyncWaitHandle { | |
17 get { | |
18 lock (this) { | |
19 if (WaitEvent == null) WaitEvent = new ManualResetEvent(IsCompleted); | |
20 return WaitEvent; | |
21 } | |
22 } | |
23 } | |
24 | |
25 public AsyncResultBase(AsyncCallback callback, Object state) { | |
26 this.Callback = callback; | |
27 this.AsyncState = state; | |
28 } | |
29 | |
30 private void CallCallback(Object state) { | |
31 if (Callback != null) Callback(this); | |
32 } | |
33 | |
34 protected void SetCompleted(Boolean synchronously, Exception error) { | |
35 this.CompletedSynchronously = synchronously; | |
36 this.Error = error; | |
37 lock (this) { | |
38 IsCompleted = true; | |
39 if (WaitEvent != null) WaitEvent.Set(); | |
104 | 40 if (MonitorWaitHandle != null) lock (MonitorWaitHandle) Monitor.Pulse(MonitorWaitHandle); |
5 | 41 } |
7
4b78cc5f116b
Fixes and improvements (some untested)
Ivo Smits <Ivo@UCIS.nl>
parents:
5
diff
changeset
|
42 if (Callback != null) { |
18
a6faa87767bb
AsyncResultBase: prevent recursive synchronous completion callback
Ivo Smits <Ivo@UCIS.nl>
parents:
7
diff
changeset
|
43 if (synchronously && !ThreadInCallback) { |
a6faa87767bb
AsyncResultBase: prevent recursive synchronous completion callback
Ivo Smits <Ivo@UCIS.nl>
parents:
7
diff
changeset
|
44 try { |
a6faa87767bb
AsyncResultBase: prevent recursive synchronous completion callback
Ivo Smits <Ivo@UCIS.nl>
parents:
7
diff
changeset
|
45 ThreadInCallback = true; |
a6faa87767bb
AsyncResultBase: prevent recursive synchronous completion callback
Ivo Smits <Ivo@UCIS.nl>
parents:
7
diff
changeset
|
46 Callback(this); |
a6faa87767bb
AsyncResultBase: prevent recursive synchronous completion callback
Ivo Smits <Ivo@UCIS.nl>
parents:
7
diff
changeset
|
47 } finally { |
a6faa87767bb
AsyncResultBase: prevent recursive synchronous completion callback
Ivo Smits <Ivo@UCIS.nl>
parents:
7
diff
changeset
|
48 ThreadInCallback = false; |
a6faa87767bb
AsyncResultBase: prevent recursive synchronous completion callback
Ivo Smits <Ivo@UCIS.nl>
parents:
7
diff
changeset
|
49 } |
7
4b78cc5f116b
Fixes and improvements (some untested)
Ivo Smits <Ivo@UCIS.nl>
parents:
5
diff
changeset
|
50 } else { |
4b78cc5f116b
Fixes and improvements (some untested)
Ivo Smits <Ivo@UCIS.nl>
parents:
5
diff
changeset
|
51 SysThreadPool.QueueUserWorkItem(CallCallback); |
4b78cc5f116b
Fixes and improvements (some untested)
Ivo Smits <Ivo@UCIS.nl>
parents:
5
diff
changeset
|
52 } |
4b78cc5f116b
Fixes and improvements (some untested)
Ivo Smits <Ivo@UCIS.nl>
parents:
5
diff
changeset
|
53 } |
5 | 54 } |
55 | |
104 | 56 public void WaitForCompletion() { |
57 lock (this) if (!IsCompleted) lock (MonitorWaitHandle) Monitor.Wait(MonitorWaitHandle); | |
58 } | |
59 | |
5 | 60 protected void ThrowError() { |
61 if (Error != null) throw Error; | |
62 } | |
63 } | |
64 } |