2 // CommunicationObject.cs
5 // Atsushi Enomoto <atsushi@ximian.com>
7 // Copyright (C) 2005 Novell, Inc. http://www.novell.com
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 using System.ServiceModel;
30 using System.Threading;
32 namespace System.ServiceModel.Channels
34 public abstract class CommunicationObject : ICommunicationObject
37 CommunicationState state = CommunicationState.Created;
38 TimeSpan open_timeout, close_timeout;
41 protected CommunicationObject ()
42 : this (new object ())
46 protected CommunicationObject (object mutex)
53 public event EventHandler Closed;
55 public event EventHandler Closing;
57 public event EventHandler Faulted;
59 public event EventHandler Opened;
61 public event EventHandler Opening;
67 public CommunicationState State {
71 protected bool IsDisposed {
72 get { return state == CommunicationState.Closed; }
75 protected object ThisLock {
79 protected internal abstract TimeSpan DefaultCloseTimeout { get; }
81 protected internal abstract TimeSpan DefaultOpenTimeout { get; }
94 protected void Fault ()
96 state = CommunicationState.Faulted;
100 public IAsyncResult BeginClose (AsyncCallback callback,
103 return BeginClose (close_timeout, callback, state);
106 public IAsyncResult BeginClose (TimeSpan timeout,
107 AsyncCallback callback, object state)
110 return OnBeginClose (timeout, callback, state);
113 public IAsyncResult BeginOpen (AsyncCallback callback,
116 return BeginOpen (open_timeout, callback, state);
119 public IAsyncResult BeginOpen (TimeSpan timeout,
120 AsyncCallback callback, object state)
123 return OnBeginOpen (timeout, callback, state);
128 Close (close_timeout);
131 public void Close (TimeSpan timeout)
138 public void EndClose (IAsyncResult result)
144 public void EndOpen (IAsyncResult result)
155 public void Open (TimeSpan timeout)
162 protected abstract void OnAbort ();
164 protected abstract IAsyncResult OnBeginClose (TimeSpan timeout,
165 AsyncCallback callback, object state);
167 protected abstract IAsyncResult OnBeginOpen (TimeSpan timeout,
168 AsyncCallback callback, object state);
170 protected abstract void OnClose (TimeSpan timeout);
172 void ProcessClosing ()
174 if (State == CommunicationState.Faulted)
175 throw new CommunicationObjectFaultedException ();
176 state = CommunicationState.Closing;
180 protected virtual void OnClosing ()
182 // This means, if this method is overriden, then
183 // Opening event is surpressed.
185 Closing (this, new EventArgs ());
188 void ProcessClosed ()
190 state = CommunicationState.Closed;
194 protected virtual void OnClosed ()
196 // This means, if this method is overriden, then
197 // Closed event is surpressed.
199 Closed (this, new EventArgs ());
202 protected abstract void OnEndClose (IAsyncResult result);
204 protected abstract void OnEndOpen (IAsyncResult result);
207 protected virtual void OnFaulted ()
209 // This means, if this method is overriden, then
210 // Opened event is surpressed.
212 Faulted (this, new EventArgs ());
215 protected abstract void OnOpen (TimeSpan timeout);
217 void ProcessOpened ()
219 state = CommunicationState.Opened;
223 protected virtual void OnOpened ()
225 // This means, if this method is overriden, then
226 // Opened event is surpressed.
228 Opened (this, new EventArgs ());
231 void ProcessOpening ()
233 ThrowIfDisposedOrImmutable ();
234 state = CommunicationState.Opening;
238 protected virtual void OnOpening ()
240 // This means, if this method is overriden, then
241 // Opening event is surpressed.
243 Opening (this, new EventArgs ());
246 protected void ThrowIfDisposed ()
249 throw new ObjectDisposedException (String.Format ("This communication object {0} is already disposed.", GetCommunicationObjectType ()));
252 protected void ThrowIfDisposedOrNotOpen ()
255 if (State == CommunicationState.Faulted)
256 throw new CommunicationObjectFaultedException ();
257 if (State != CommunicationState.Opened)
258 throw new InvalidOperationException (String.Format ("The communication object {0} must be at opened state.", GetCommunicationObjectType ()));
261 protected void ThrowIfDisposedOrImmutable ()
264 // hmm, according to msdn, Closing is OK here.
266 case CommunicationState.Faulted:
267 throw new CommunicationObjectFaultedException ();
268 case CommunicationState.Opening:
269 case CommunicationState.Opened:
270 throw new InvalidOperationException (String.Format ("The communication object {0} is not at created state.", GetType ()));
274 protected virtual Type GetCommunicationObjectType ()
282 class SimpleAsyncResult : IAsyncResult
284 CommunicationState comm_state;
287 public SimpleAsyncResult (
288 CommunicationState communicationState,
289 TimeSpan timeout, AsyncCallback callback,
292 comm_state = communicationState;
293 async_state = asyncState;
296 public object AsyncState {
297 get { return async_state; }
301 public WaitHandle AsyncWaitHandle {
302 get { throw new NotImplementedException (); }
306 public bool CompletedSynchronously {
307 get { throw new NotImplementedException (); }
311 public bool IsCompleted {
312 get { throw new NotImplementedException (); }