Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Channels / RequestChannel.cs / 1 / RequestChannel.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- namespace System.ServiceModel.Channels { using System.Collections.Generic; using System.ServiceModel; using System.Diagnostics; using System.ServiceModel.Diagnostics; using System.Threading; abstract class RequestChannel : ChannelBase, IRequestChannel { bool manualAddressing; ListoutstandingRequests = new List (); EndpointAddress to; Uri via; ManualResetEvent closedEvent; bool closed; protected RequestChannel(ChannelManagerBase channelFactory, EndpointAddress to, Uri via, bool manualAddressing) : base(channelFactory) { if (!manualAddressing) { if (to == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("to"); } } this.manualAddressing = manualAddressing; this.to = to; this.via = via; } protected bool ManualAddressing { get { return this.manualAddressing; } } public EndpointAddress RemoteAddress { get { return this.to; } } public Uri Via { get { return this.via; } } protected void AbortPendingRequests() { IRequestBase[] requestsToAbort = CopyPendingRequests(false); if (requestsToAbort != null) { foreach (IRequestBase request in requestsToAbort) { request.Abort(this); } } } protected IAsyncResult BeginWaitForPendingRequests(TimeSpan timeout, AsyncCallback callback, object state) { IRequestBase[] pendingRequests = SetupWaitForPendingRequests(); return new WaitForPendingRequestsAsyncResult(timeout, this, pendingRequests, callback, state); } protected void EndWaitForPendingRequests(IAsyncResult result) { WaitForPendingRequestsAsyncResult.End(result); } void FinishClose() { lock (outstandingRequests) { if (!closed) { closed = true; if (closedEvent != null) { this.closedEvent.Close(); } } } } IRequestBase[] SetupWaitForPendingRequests() { return this.CopyPendingRequests(true); } protected void WaitForPendingRequests(TimeSpan timeout) { IRequestBase[] pendingRequests = SetupWaitForPendingRequests(); if (pendingRequests != null) { if (!closedEvent.WaitOne(timeout, false)) { foreach (IRequestBase request in pendingRequests) { request.Abort(this); } } } FinishClose(); } IRequestBase[] CopyPendingRequests(bool createEventIfNecessary) { IRequestBase[] requests = null; lock (outstandingRequests) { if (outstandingRequests.Count > 0) { requests = new IRequestBase[outstandingRequests.Count]; outstandingRequests.CopyTo(requests); outstandingRequests.Clear(); if (createEventIfNecessary && closedEvent == null) { closedEvent = new ManualResetEvent(false); } } } return requests; } protected void FaultPendingRequests() { IRequestBase[] requestsToFault = CopyPendingRequests(false); if (requestsToFault != null) { foreach (IRequestBase request in requestsToFault) { request.Fault(this); } } } public override T GetProperty () { if (typeof(T) == typeof(IRequestChannel)) { return (T)(object)this; } T baseProperty = base.GetProperty (); if (baseProperty != null) { return baseProperty; } return default(T); } protected override void OnAbort() { AbortPendingRequests(); } void ReleaseRequest(IRequestBase request) { lock (outstandingRequests) { // Remove supports the connection having been removed, so don't need extra Contains() check, // even though this may have been removed by Abort() outstandingRequests.Remove(request); if (outstandingRequests.Count == 0) { if (!closed && closedEvent != null) { closedEvent.Set(); } } } } void TrackRequest(IRequestBase request) { lock (outstandingRequests) { ThrowIfDisposedOrNotOpen(); // make sure that we haven't already snapshot our collection outstandingRequests.Add(request); } } public IAsyncResult BeginRequest(Message message, AsyncCallback callback, object state) { return this.BeginRequest(message, this.DefaultSendTimeout, callback, state); } public IAsyncResult BeginRequest(Message message, TimeSpan timeout, AsyncCallback callback, object state) { if (message == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message"); if (timeout < TimeSpan.Zero) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new ArgumentOutOfRangeException("timeout", timeout, SR.GetString(SR.SFxTimeoutOutOfRange0))); ThrowIfDisposedOrNotOpen(); AddHeadersTo(message); IAsyncRequest asyncRequest = CreateAsyncRequest(message, callback, state); TrackRequest(asyncRequest); bool throwing = true; try { asyncRequest.BeginSendRequest(message, timeout); throwing = false; } finally { if (throwing) { ReleaseRequest(asyncRequest); } } return asyncRequest; } protected abstract IRequest CreateRequest(Message message); protected abstract IAsyncRequest CreateAsyncRequest(Message message, AsyncCallback callback, object state); public Message EndRequest(IAsyncResult result) { if (result == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("result"); } IAsyncRequest asyncRequest = result as IAsyncRequest; if (asyncRequest == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("result", SR.GetString(SR.InvalidAsyncResult)); } try { Message reply = asyncRequest.End(); if (DiagnosticUtility.ShouldTraceInformation) TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.RequestChannelReplyReceived, reply); return reply; } finally { ReleaseRequest(asyncRequest); } } public Message Request(Message message) { return this.Request(message, this.DefaultSendTimeout); } public Message Request(Message message, TimeSpan timeout) { if (message == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message"); } if (timeout < TimeSpan.Zero) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new ArgumentOutOfRangeException("timeout", timeout, SR.GetString(SR.SFxTimeoutOutOfRange0))); ThrowIfDisposedOrNotOpen(); AddHeadersTo(message); IRequest request = CreateRequest(message); TrackRequest(request); try { Message reply; TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); TimeSpan savedTimeout = timeoutHelper.RemainingTime(); try { request.SendRequest(message, savedTimeout); } catch (TimeoutException timeoutException) { throw TraceUtility.ThrowHelperError(new TimeoutException(SR.GetString(SR.RequestChannelSendTimedOut, savedTimeout), timeoutException), message); } savedTimeout = timeoutHelper.RemainingTime(); try { reply = request.WaitForReply(savedTimeout); } catch (TimeoutException timeoutException) { throw TraceUtility.ThrowHelperError(new TimeoutException(SR.GetString(SR.RequestChannelWaitForReplyTimedOut, savedTimeout), timeoutException), message); } if (DiagnosticUtility.ShouldTraceInformation) TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.RequestChannelReplyReceived, reply); return reply; } finally { ReleaseRequest(request); } } protected virtual void AddHeadersTo(Message message) { if (!manualAddressing && to != null) { to.ApplyTo(message); } } class WaitForPendingRequestsAsyncResult : AsyncResult { static WaitOrTimerCallback completeWaitCallBack = new WaitOrTimerCallback(OnCompleteWaitCallBack); IRequestBase[] pendingRequests; RequestChannel requestChannel; TimeSpan timeout; RegisteredWaitHandle waitHandle; public WaitForPendingRequestsAsyncResult(TimeSpan timeout, RequestChannel requestChannel, IRequestBase[] pendingRequests, AsyncCallback callback, object state) : base(callback, state) { this.requestChannel = requestChannel; this.pendingRequests = pendingRequests; this.timeout = timeout; if (this.timeout == TimeSpan.Zero || this.pendingRequests == null) { AbortRequests(); CleanupEvents(); Complete(true); } else { this.waitHandle = ThreadPool.UnsafeRegisterWaitForSingleObject(this.requestChannel.closedEvent, completeWaitCallBack, this, TimeoutHelper.ToMilliseconds(timeout), true); } } void AbortRequests() { if (pendingRequests != null) { foreach(IRequestBase request in pendingRequests) { request.Abort(this.requestChannel); } } } void CleanupEvents() { if (requestChannel.closedEvent != null) { if (waitHandle != null) { waitHandle.Unregister(requestChannel.closedEvent); } requestChannel.FinishClose(); } } static void OnCompleteWaitCallBack(object state, bool timedOut) { WaitForPendingRequestsAsyncResult thisPtr = (WaitForPendingRequestsAsyncResult)state; Exception completionException = null; try { if (timedOut) { thisPtr.AbortRequests(); } thisPtr.CleanupEvents(); } #pragma warning suppress 56500 // [....], transferring exception to another thread catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) { throw; } completionException = e; } thisPtr.Complete(false, completionException); } public static void End(IAsyncResult result) { AsyncResult.End (result); } } } interface IRequestBase { void Abort(RequestChannel requestChannel); void Fault(RequestChannel requestChannel); } interface IRequest : IRequestBase { void SendRequest(Message message, TimeSpan timeout); Message WaitForReply(TimeSpan timeout); } interface IAsyncRequest : IAsyncResult, IRequestBase { void BeginSendRequest(Message message, TimeSpan timeout); Message End(); } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- TableSectionStyle.cs
- LoginAutoFormat.cs
- SrgsToken.cs
- DataGridViewIntLinkedList.cs
- WebBrowserProgressChangedEventHandler.cs
- IssuedTokenClientElement.cs
- DecimalAnimationUsingKeyFrames.cs
- EllipseGeometry.cs
- ChannelCredentials.cs
- DocumentOrderComparer.cs
- EntitySetDataBindingList.cs
- ConsoleTraceListener.cs
- CodeArrayCreateExpression.cs
- DataBindingExpressionBuilder.cs
- Int32Rect.cs
- oledbmetadatacollectionnames.cs
- MessageBox.cs
- TextSpan.cs
- Thumb.cs
- EventLogPermissionAttribute.cs
- Events.cs
- XmlComment.cs
- UnmanagedMemoryStream.cs
- RSAOAEPKeyExchangeDeformatter.cs
- StyleModeStack.cs
- PkcsUtils.cs
- FtpCachePolicyElement.cs
- ContainsRowNumberChecker.cs
- ActiveXMessageFormatter.cs
- ObjectStateFormatter.cs
- SchemaLookupTable.cs
- ProfilePropertySettingsCollection.cs
- HostAdapter.cs
- ConfigurationElementProperty.cs
- _Events.cs
- DataGridViewIntLinkedList.cs
- LinkDescriptor.cs
- DockingAttribute.cs
- ComplexPropertyEntry.cs
- fixedPageContentExtractor.cs
- PkcsUtils.cs
- Odbc32.cs
- EntityDataSourceUtil.cs
- GeometryGroup.cs
- ResourcePermissionBaseEntry.cs
- CqlLexerHelpers.cs
- BuildTopDownAttribute.cs
- UserCancellationException.cs
- ServiceObjectContainer.cs
- StringFormat.cs
- Vector.cs
- SqlCharStream.cs
- SignerInfo.cs
- DataTablePropertyDescriptor.cs
- SchemaDeclBase.cs
- MethodExpression.cs
- SecurityKeyIdentifier.cs
- KeySpline.cs
- BitmapMetadata.cs
- PermissionSetTriple.cs
- MemberAccessException.cs
- ByteAnimationBase.cs
- CultureSpecificCharacterBufferRange.cs
- XPathMessageFilter.cs
- XmlSchemaSubstitutionGroup.cs
- StaticExtension.cs
- DataGridItemAttachedStorage.cs
- RangeValidator.cs
- NativeWindow.cs
- TransformerTypeCollection.cs
- XPathPatternBuilder.cs
- HttpHostedTransportConfiguration.cs
- ValidationError.cs
- LeafCellTreeNode.cs
- XomlCompilerError.cs
- OdbcEnvironment.cs
- TransformerTypeCollection.cs
- SafeViewOfFileHandle.cs
- recordstatefactory.cs
- SessionStateItemCollection.cs
- DecimalAnimationBase.cs
- OdbcParameter.cs
- IDReferencePropertyAttribute.cs
- ThousandthOfEmRealPoints.cs
- EventHandlersStore.cs
- ListBoxAutomationPeer.cs
- Substitution.cs
- GeometryDrawing.cs
- WebReferencesBuildProvider.cs
- ResourceContainer.cs
- StylusPointProperty.cs
- XmlILOptimizerVisitor.cs
- KeyFrames.cs
- SeekStoryboard.cs
- XsltContext.cs
- RegexCode.cs
- QuestionEventArgs.cs
- FixedFindEngine.cs
- ProtocolsConfigurationEntry.cs
- DataRelationCollection.cs