added samples
[windows-sources.git] / sdk / samples / WCFSamples / TechnologySamples / Extensibility / Transport / UdpActivation / CS / UDPActivation / AsyncResult.cs
blob2d4d3c878a9923e1726498c27fd02d9c744ea854
1 // ----------------------------------------------------------------------------
2 // Copyright (C) 2003-2005 Microsoft Corporation, All rights reserved.
3 // ----------------------------------------------------------------------------
5 using System;
6 using System.Diagnostics;
7 using System.Threading;
9 namespace Microsoft.ServiceModel.Samples
11 /// <summary>
12 /// A generic base class for IAsyncResult implementations
13 /// that wraps a ManualResetEvent.
14 /// </summary>
15 abstract class AsyncResult : IAsyncResult
17 AsyncCallback callback;
18 object state;
19 bool completedSynchronously;
20 bool endCalled;
21 Exception exception;
22 bool isCompleted;
23 ManualResetEvent manualResetEvent;
24 object thisLock;
26 protected AsyncResult(AsyncCallback callback, object state)
28 this.callback = callback;
29 this.state = state;
30 this.thisLock = new object();
33 public object AsyncState
35 get
37 return state;
41 public WaitHandle AsyncWaitHandle
43 get
45 if (manualResetEvent != null)
47 return manualResetEvent;
50 lock (ThisLock)
52 if (manualResetEvent == null)
54 manualResetEvent = new ManualResetEvent(isCompleted);
58 return manualResetEvent;
62 public bool CompletedSynchronously
64 get
66 return completedSynchronously;
70 public bool IsCompleted
72 get
74 return isCompleted;
78 object ThisLock
80 get
82 return this.thisLock;
86 // Call this version of complete when your asynchronous operation is complete. This will update the state
87 // of the operation and notify the callback.
88 protected void Complete(bool completedSynchronously)
90 if (isCompleted)
92 // It is a bug to call Complete twice.
93 throw new InvalidOperationException("Cannot call Complete twice");
96 this.completedSynchronously = completedSynchronously;
98 if (completedSynchronously)
100 // If we completedSynchronously, then there is no chance that the manualResetEvent was created so
101 // we do not need to worry about a race condition.
102 Debug.Assert(this.manualResetEvent == null, "No ManualResetEvent should be created for a synchronous AsyncResult.");
103 this.isCompleted = true;
105 else
107 lock (ThisLock)
109 this.isCompleted = true;
110 if (this.manualResetEvent != null)
112 this.manualResetEvent.Set();
117 // If the callback throws, there is a bug in the callback implementation
118 if (callback != null)
120 callback(this);
124 // Call this version of complete if you raise an exception during processing. In addition to notifying
125 // the callback, it will capture the exception and store it to be thrown during AsyncResult.End.
126 protected void Complete(bool completedSynchronously, Exception exception)
128 this.exception = exception;
129 Complete(completedSynchronously);
132 // End should be called when the End function for the asynchronous operation is complete. It
133 // ensures the asynchronous operation is complete, and does some common validation.
134 protected static TAsyncResult End<TAsyncResult>(IAsyncResult result)
135 where TAsyncResult : AsyncResult
137 if (result == null)
139 throw new ArgumentNullException("result");
142 TAsyncResult asyncResult = result as TAsyncResult;
144 if (asyncResult == null)
146 throw new ArgumentException("Invalid async result.", "result");
149 if (asyncResult.endCalled)
151 throw new InvalidOperationException("Async object already ended.");
154 asyncResult.endCalled = true;
156 if (!asyncResult.isCompleted)
158 asyncResult.AsyncWaitHandle.WaitOne();
161 if (asyncResult.manualResetEvent != null)
163 asyncResult.manualResetEvent.Close();
166 if (asyncResult.exception != null)
168 throw asyncResult.exception;
171 return asyncResult;
175 //An AsyncResult that completes as soon as it is instantiated.
176 class CompletedAsyncResult : AsyncResult
178 public CompletedAsyncResult(AsyncCallback callback, object state)
179 : base(callback, state)
181 Complete(true);
184 public static void End(IAsyncResult result)
186 AsyncResult.End<CompletedAsyncResult>(result);
190 //A strongly typed AsyncResult
191 abstract class TypedAsyncResult<T> : AsyncResult
193 T data;
195 protected TypedAsyncResult(AsyncCallback callback, object state)
196 : base(callback, state)
200 public T Data
202 get { return data; }
205 protected void Complete(T data, bool completedSynchronously)
207 this.data = data;
208 Complete(completedSynchronously);
211 public static T End(IAsyncResult result)
213 TypedAsyncResult<T> typedResult = AsyncResult.End<TypedAsyncResult<T>>(result);
214 return typedResult.Data;
218 //A strongly typed AsyncResult that completes as soon as it is instantiated.
219 class TypedCompletedAsyncResult<T> : TypedAsyncResult<T>
221 public TypedCompletedAsyncResult(T data, AsyncCallback callback, object state)
222 : base(callback, state)
224 Complete(data, true);
227 public new static T End(IAsyncResult result)
229 TypedCompletedAsyncResult<T> completedResult = result as TypedCompletedAsyncResult<T>;
230 if (completedResult == null)
232 throw new ArgumentException("Invalid async result.", "result");
235 return TypedAsyncResult<T>.End(completedResult);