2005-01-31 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / class / Microsoft.Web.Services / Microsoft.Web.Services / AsyncResult.cs
1 //
2 // Microsoft.Web.Services.AsyncResult.cs
3 //
4 // Author: Todd Berman <tberman@gentoo.org>
5 //
6 // (C) 2003 Todd Berman
7
8 using System;
9 using System.Threading;
10
11 namespace Microsoft.Web.Services
12 {
13         public class AsyncResult : IAsyncResult
14         {
15                 private AsyncCallback _callback;
16                 private bool _completed;
17                 private bool _completedSync;
18                 private bool _endCalled;
19                 private ManualResetEvent _event;
20                 private Exception _exception;
21                 private object _state;
22
23                 protected AsyncResult (object s) : this (null, s)
24                 {
25                 }
26
27                 protected AsyncResult (AsyncCallback call, object s) : base ()
28                 {
29                         _callback = call;
30                         _state = s;
31                 }
32
33                 protected AsyncResult () : this (null, null)
34                 {
35                 }
36
37                 protected void Complete (bool csync, Exception e)
38                 {
39                         _completed = true;
40                         _completedSync = csync;
41                         _exception = e;
42
43                         if(_event != null) {
44                                 _event.Set ();
45                         }
46                         try {
47                                 if(_callback != null) {
48                                         _callback (this);
49                                 }
50                         } catch (Exception) {
51                                 ThreadPool.QueueUserWorkItem (new WaitCallback (ThrowException), this);
52                         }
53                 }
54
55                 protected void Complete (bool csync)
56                 {
57                         this.Complete (csync, null);
58                 }
59
60                 public static void End (IAsyncResult result)
61                 {
62                         if(result == null) {
63                                 throw new ArgumentNullException ("result");
64                         }
65                         AsyncResult mws_result = (AsyncResult) result;
66
67                         if(mws_result == null) {
68                                 throw new ArgumentException ("Invalid result");
69                         }
70
71                         if(mws_result._endCalled == true) {
72                                 throw new InvalidOperationException ("Async Operation already finished");
73                         }
74
75                         mws_result._endCalled = true;
76
77                         if(mws_result._completed == true) {
78                                 mws_result.AsyncWaitHandle.WaitOne ();
79                         }
80
81                         if(mws_result._exception != null) {
82                                 throw mws_result._exception;
83                         }
84                 }
85                 
86                 private void ThrowException (object o)
87                 {
88                         Exception e = (Exception) o;
89                         throw e;
90                 }
91
92                 public object AsyncState {
93                         get { return _state; }
94                 }
95
96                 public WaitHandle AsyncWaitHandle {
97                         get {
98                                 if(_event == null) {
99                                         bool complete = _completed;
100
101                                         lock (this) {
102                                                 _event = new ManualResetEvent (_completed);
103                                         }
104                                         if(complete == true || _completed == false) {
105                                                 _event.Set ();
106                                         }
107                                 }
108                                 return _event;
109                         }
110                 }
111
112                 public bool CompletedSynchronously {
113                         get { return _completedSync; }
114                 }
115
116                 public bool IsCompleted {
117                         get { return _completed; }
118                 }
119         }
120 }