Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx40 / System.ServiceModel.Discovery / System / ServiceModel / Discovery / DiscoveryClientChannelBase.cs / 1305376 / DiscoveryClientChannelBase.cs
//---------------------------------------------------------------- // Copyright (c) Microsoft Corporation. All rights reserved. //--------------------------------------------------------------- namespace System.ServiceModel.Discovery { using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Runtime; using System.Security; using System.ServiceModel.Channels; using System.Threading; abstract partial class DiscoveryClientChannelBase: ChannelBase where TChannel : class, IChannel { TChannel innerChannel; IChannelFactory innerChannelFactory; FindCriteria findCriteria; DiscoveryEndpointProvider discoveryEndpointProvider; DiscoveryClient discoveryClient; InputQueue discoveredEndpoints; Exception exception; int totalExpectedEndpoints; int totalDiscoveredEndpoints; bool discoveryCompleted; [Fx.Tag.SynchronizationObject] object thisLock; public DiscoveryClientChannelBase( ChannelManagerBase channelManagerBase, IChannelFactory innerChannelFactory, FindCriteria findCriteria, DiscoveryEndpointProvider discoveryEndpointProvider) : base(channelManagerBase) { Fx.Assert(findCriteria != null, "The findCriteria must be non null."); Fx.Assert(discoveryEndpointProvider != null, "The discoveryEndpointProvider must be non null."); Fx.Assert(innerChannelFactory != null, "The innerChannelFactory must be non null."); this.innerChannelFactory = innerChannelFactory; this.findCriteria = findCriteria; this.discoveryEndpointProvider = discoveryEndpointProvider; this.discoveredEndpoints = new InputQueue (); this.totalExpectedEndpoints = int.MaxValue; this.totalDiscoveredEndpoints = 0; this.discoveryCompleted = false; this.thisLock = new object(); } protected TChannel InnerChannel { get { return this.innerChannel; } } public override T GetProperty () { T baseProperty = base.GetProperty (); if (baseProperty != null) { return baseProperty; } if (this.innerChannel != null) { return this.InnerChannel.GetProperty (); } return null; } protected override void OnOpen(TimeSpan timeout) { this.innerChannel = this.BuildChannel(timeout); this.innerChannel.Faulted += new EventHandler(OnInnerChannelFaulted); } protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state) { return new DiscoveryChannelBuilderAsyncResult( this, timeout, callback, state); } protected override void OnEndOpen(IAsyncResult result) { this.innerChannel = DiscoveryChannelBuilderAsyncResult.End(result); this.innerChannel.Faulted += new EventHandler(OnInnerChannelFaulted); } protected override void OnClosing() { if (this.innerChannel != null) { this.innerChannel.Faulted -= new EventHandler(OnInnerChannelFaulted); } base.OnClosing(); } protected override void OnClose(TimeSpan timeout) { if (this.innerChannel != null) { this.innerChannel.Close(timeout); } } protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state) { return new CloseAsyncResult( this.innerChannel, timeout, callback, state); } protected override void OnEndClose(IAsyncResult result) { CloseAsyncResult.End(result); } protected override void OnAbort() { if (this.innerChannel != null) { this.innerChannel.Abort(); } } void OnInnerChannelFaulted(object sender, EventArgs e) { this.Fault(); } public TChannel BuildChannel(TimeSpan timeout) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); this.InitializeAndFindAsync(); TChannel innerChannel = null; bool completed = false; EndpointDiscoveryMetadata currentEndpointDiscoveryMetadata = null; try { do { try { currentEndpointDiscoveryMetadata = this.discoveredEndpoints.Dequeue(timeoutHelper.RemainingTime()); } catch (TimeoutException te) { throw FxTrace.Exception.AsError(new TimeoutException(SR.DiscoveryClientChannelOpenTimeout(timeoutHelper.OriginalTimeout), te)); } if (currentEndpointDiscoveryMetadata == null) { if (this.totalDiscoveredEndpoints < 1) { throw FxTrace.Exception.AsError(new EndpointNotFoundException(SR.DiscoveryClientChannelEndpointNotFound, this.exception)); } else { throw FxTrace.Exception.AsError(new EndpointNotFoundException(SR.DiscoveryClientChannelCreationFailed(this.totalDiscoveredEndpoints), this.exception)); } } if (timeoutHelper.RemainingTime() == TimeSpan.Zero) { throw FxTrace.Exception.AsError(new TimeoutException(SR.DiscoveryClientChannelOpenTimeout(timeoutHelper.OriginalTimeout))); } if (currentEndpointDiscoveryMetadata.ListenUris.Count == 0) { completed = this.CreateChannel( ref innerChannel, currentEndpointDiscoveryMetadata.Address, currentEndpointDiscoveryMetadata.Address.Uri, timeoutHelper); } else { foreach (Uri listenUri in currentEndpointDiscoveryMetadata.ListenUris) { completed = this.CreateChannel( ref innerChannel, currentEndpointDiscoveryMetadata.Address, listenUri, timeoutHelper); if (completed) { break; } } } } while (!completed); } finally { if (completed && TD.InnerChannelOpenSuccededIsEnabled()) { TD.InnerChannelOpenSucceded( currentEndpointDiscoveryMetadata.Address.ToString(), GetVia(innerChannel).ToString()) ; } this.Cleanup(timeoutHelper.RemainingTime()); } return innerChannel; } bool CreateChannel(ref TChannel innerChannel, EndpointAddress to, Uri via, TimeoutHelper timeoutHelper) { bool completed = false; Exception exception = null; try { innerChannel = this.innerChannelFactory.CreateChannel(to, via); innerChannel.Open(timeoutHelper.RemainingTime()); completed = true; } catch (TimeoutException timeoutException) { throw FxTrace.Exception.AsError(new TimeoutException(SR.DiscoveryClientChannelOpenTimeout(timeoutHelper.OriginalTimeout), timeoutException)); } catch (CommunicationException communicationException) { exception = communicationException; } catch (ArgumentException argumentException) { exception = argumentException; } catch (InvalidOperationException invalidOperationException) { exception = invalidOperationException; } finally { if (exception != null) { TraceInnerChannelFailure(innerChannel, to, via, exception); } if (!completed && innerChannel != null) { innerChannel.Abort(); innerChannel = null; } } return completed; } void OnFindProgressChanged(object sender, FindProgressChangedEventArgs e) { lock (this.thisLock) { if (!this.discoveryCompleted) { this.discoveredEndpoints.EnqueueAndDispatch(e.EndpointDiscoveryMetadata, null, false); if (++this.totalDiscoveredEndpoints == this.totalExpectedEndpoints) { this.discoveryCompleted = true; this.discoveredEndpoints.Shutdown(); } } } } void OnFindCompleted(object sender, FindCompletedEventArgs e) { lock (this.thisLock) { if(!this.discoveryCompleted) { if (e.Error != null || e.Cancelled || this.totalDiscoveredEndpoints == e.Result.Endpoints.Count) { this.exception = e.Error; this.discoveryCompleted = true; this.discoveredEndpoints.Shutdown(); } else { this.totalExpectedEndpoints = e.Result.Endpoints.Count; } } } } [SecuritySafeCritical] void InitializeAndFindAsync() { DiscoveryEndpoint discoveryEndpoint = this.discoveryEndpointProvider.GetDiscoveryEndpoint(); if (discoveryEndpoint == null) { throw FxTrace.Exception.AsError( new InvalidOperationException( SR.DiscoveryMethodImplementationReturnsNull("GetDiscoveryEndpoint", this.discoveryEndpointProvider.GetType()))); } this.discoveryClient = new DiscoveryClient(discoveryEndpoint); this.discoveryClient.FindProgressChanged += new EventHandler (OnFindProgressChanged); this.discoveryClient.FindCompleted += new EventHandler (OnFindCompleted); SynchronizationContext originalSynchronizationContext = SynchronizationContext.Current; if (originalSynchronizationContext != null) { SynchronizationContext.SetSynchronizationContext(null); if (TD.SynchronizationContextSetToNullIsEnabled()) { TD.SynchronizationContextSetToNull(); } } try { // AsyncOperation uses the SynchronizationContext set during its // initialization to Post the FindProgressed and FindProgressCompleted // events. Hence even if the async operation does not complete // synchronously, the right SynchronizationContext will be used by // AsyncOperation. this.discoveryClient.FindAsync(this.findCriteria, this); } finally { if (originalSynchronizationContext != null) { SynchronizationContext.SetSynchronizationContext(originalSynchronizationContext); if (TD.SynchronizationContextResetIsEnabled()) { TD.SynchronizationContextReset(originalSynchronizationContext.GetType().ToString()); } } } if (TD.FindInitialitedInDiscoveryClientChannelIsEnabled()) { TD.FindInitialitedInDiscoveryClientChannel(); } } void Cleanup(TimeSpan timeout) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); Exception exception = null; lock (this.thisLock) { this.discoveryCompleted = true; } try { this.discoveryClient.CancelAsync(this); ((ICommunicationObject)this.discoveryClient).Close(timeoutHelper.RemainingTime()); } catch (TimeoutException timeoutException) { exception = timeoutException; } catch (CommunicationException communicationException) { exception = communicationException; } finally { if (exception != null && TD.DiscoveryClientInClientChannelFailedToCloseIsEnabled()) { TD.DiscoveryClientInClientChannelFailedToClose(exception); } } this.discoveredEndpoints.Dispose(); this.discoveryClient = null; this.discoveredEndpoints = null; this.findCriteria = null; this.discoveryEndpointProvider = null; this.innerChannelFactory = null; } static void TraceInnerChannelFailure(TChannel innerChannel, EndpointAddress to, Uri via, Exception exception) { if (innerChannel == null && TD.InnerChannelCreationFailedIsEnabled()) { TD.InnerChannelCreationFailed(to.ToString(), via.ToString(), exception); } else if (innerChannel != null && TD.InnerChannelOpenFailedIsEnabled()) { TD.InnerChannelOpenFailed(to.ToString(), via.ToString(), exception); } } static Uri GetVia(TChannel innerChannel) { Fx.Assert(innerChannel != null, "TChannel must be non null"); IOutputChannel outputChannel = innerChannel as IOutputChannel; if (outputChannel != null) { return outputChannel.Via; } IRequestChannel requestChannel = innerChannel as IRequestChannel; if (requestChannel != null) { return requestChannel.Via; } Fx.Assert("TChannel must be a type derived from IOutputChannel or IRequestChannel"); return null; } sealed class DiscoveryChannelBuilderAsyncResult : IteratorAsyncResult { static AsyncStep openStep; static AsyncStep dequeueStep; TChannel innerChannel; EndpointDiscoveryMetadata currentEndpointDiscoveryMetadata; DiscoveryClientChannelBase discoveryClientChannelBase; public DiscoveryChannelBuilderAsyncResult( DiscoveryClientChannelBase discoveryClientChannelBase, TimeSpan timeout, AsyncCallback callback, object state) : base(callback, state) { this.discoveryClientChannelBase = discoveryClientChannelBase; this.Start(this, timeout); } public static TChannel End(IAsyncResult result) { DiscoveryChannelBuilderAsyncResult thisPtr = AsyncResult.End (result); thisPtr.discoveryClientChannelBase.Cleanup(thisPtr.RemainingTime()); return thisPtr.innerChannel; } protected override IEnumerator GetAsyncSteps() { this.discoveryClientChannelBase.InitializeAndFindAsync(); while (true) { this.currentEndpointDiscoveryMetadata = null; yield return DiscoveryChannelBuilderAsyncResult.GetDequeueStep(); Exception ex = this.CheckEndpointDiscoveryMetadataAndGetException(); if (ex != null) { this.CompleteOnce(ex); yield break; } bool checkListenUris = (currentEndpointDiscoveryMetadata.ListenUris.Count > 0); int index = 0; do { if (checkListenUris) { this.CreateChannel( this.currentEndpointDiscoveryMetadata.Address, this.currentEndpointDiscoveryMetadata.ListenUris[index++]); } else { this.CreateChannel( this.currentEndpointDiscoveryMetadata.Address, this.currentEndpointDiscoveryMetadata.Address.Uri); } if (this.innerChannel != null) { yield return DiscoveryChannelBuilderAsyncResult.GetOpenStep(); if (this.innerChannel != null) { // The channel was successfully opened if (TD.InnerChannelOpenSuccededIsEnabled()) { TD.InnerChannelOpenSucceded( this.currentEndpointDiscoveryMetadata.Address.ToString(), GetVia(this.innerChannel).ToString()); } yield break; } } } while (index < this.currentEndpointDiscoveryMetadata.ListenUris.Count); } } static AsyncStep GetDequeueStep() { if (dequeueStep == null) { dequeueStep = DiscoveryChannelBuilderAsyncResult.CallAsync( (thisPtr, t, c, s) => thisPtr.discoveryClientChannelBase.discoveredEndpoints.BeginDequeue(thisPtr.RemainingTime(), c, s), (thisPtr, r) => thisPtr.currentEndpointDiscoveryMetadata = thisPtr.discoveryClientChannelBase.discoveredEndpoints.EndDequeue(r), new IAsyncCatch[] { new DiscoveryChannelBuilderAsyncResult.AsyncCatch (HandleTimeoutException) }); } return dequeueStep; } static AsyncStep GetOpenStep() { if (openStep == null) { openStep = DiscoveryChannelBuilderAsyncResult.CallAsync( (thisPtr, t, c, s) => thisPtr.innerChannel.BeginOpen(thisPtr.RemainingTime(), c, s), (thisPtr, r) => thisPtr.innerChannel.EndOpen(r), new IAsyncCatch[] { new DiscoveryChannelBuilderAsyncResult.AsyncCatch (HandleTimeoutException), new DiscoveryChannelBuilderAsyncResult.AsyncCatch (HandleCommunicationException), new DiscoveryChannelBuilderAsyncResult.AsyncCatch (HandleException) }); } return openStep; } static Exception HandleTimeoutException(DiscoveryChannelBuilderAsyncResult thisPtr, TimeoutException e) { if (thisPtr.innerChannel != null) { thisPtr.innerChannel.Abort(); thisPtr.innerChannel = null; } return new TimeoutException(SR.DiscoveryClientChannelOpenTimeout(thisPtr.OriginalTimeout), e); } static Exception HandleException(DiscoveryChannelBuilderAsyncResult thisPtr, Exception e) { if (thisPtr.innerChannel != null) { thisPtr.innerChannel.Abort(); thisPtr.innerChannel = null; } return e; } static Exception HandleCommunicationException(DiscoveryChannelBuilderAsyncResult thisPtr, CommunicationException e) { if (thisPtr.innerChannel != null) { thisPtr.innerChannel.Abort(); if (TD.InnerChannelOpenFailedIsEnabled()) { TD.InnerChannelOpenFailed( thisPtr.currentEndpointDiscoveryMetadata.Address.ToString(), GetVia(thisPtr.innerChannel).ToString(), e); } thisPtr.innerChannel = null; } return null; } void CreateChannel(EndpointAddress address, Uri listenUri) { Exception exception = null; try { this.innerChannel = this.discoveryClientChannelBase.innerChannelFactory.CreateChannel( address, listenUri); } catch (ArgumentException argumentException) { exception = argumentException; } catch (InvalidOperationException invalidOperationException) { exception = invalidOperationException; } catch (CommunicationException communicationException) { exception = communicationException; this.CompleteOnce(communicationException); } finally { if (exception != null && TD.InnerChannelCreationFailedIsEnabled()) { TD.InnerChannelCreationFailed(address.ToString(), listenUri.ToString(), exception); } } } Exception CheckEndpointDiscoveryMetadataAndGetException() { if (this.RemainingTime() == TimeSpan.Zero) { return new TimeoutException(SR.DiscoveryClientChannelOpenTimeout(this.OriginalTimeout)); } if (this.currentEndpointDiscoveryMetadata == null) { string exceptionMessage = (this.discoveryClientChannelBase.totalDiscoveredEndpoints < 1) ? SR.DiscoveryClientChannelEndpointNotFound : SR.DiscoveryClientChannelCreationFailed(this.discoveryClientChannelBase.totalDiscoveredEndpoints); return new EndpointNotFoundException(exceptionMessage, this.discoveryClientChannelBase.exception); } return null; } } class CloseAsyncResult : AsyncResult { TChannel innerChannel; public CloseAsyncResult(TChannel innerChannel, TimeSpan timeout, AsyncCallback callback, object state) : base(callback, state) { this.innerChannel = innerChannel; if (this.innerChannel != null) { IAsyncResult closeResult = this.innerChannel.BeginClose( timeout, PrepareAsyncCompletion(new AsyncCompletion(OnCloseCompleted)), this); if (closeResult.CompletedSynchronously && OnCloseCompleted(closeResult)) { this.Complete(true); } } else { this.Complete(true); } } public static void End(IAsyncResult result) { AsyncResult.End (result); } bool OnCloseCompleted(IAsyncResult result) { this.innerChannel.EndClose(result); return true; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- Component.cs
- VisualStyleTypesAndProperties.cs
- DateTimeParse.cs
- CodePageEncoding.cs
- TimeManager.cs
- XmlChildNodes.cs
- GradientStopCollection.cs
- ServiceModelSecurityTokenTypes.cs
- DataServiceExpressionVisitor.cs
- DependencyPropertyKind.cs
- ListControlConvertEventArgs.cs
- ArraySegment.cs
- ReadOnlyTernaryTree.cs
- InternalResources.cs
- PersonalizationState.cs
- WrapperSecurityCommunicationObject.cs
- CqlErrorHelper.cs
- XmlSerializableReader.cs
- SystemWebCachingSectionGroup.cs
- LockCookie.cs
- dbenumerator.cs
- ColorMap.cs
- SvcMapFileLoader.cs
- DiagnosticsConfiguration.cs
- QilGeneratorEnv.cs
- GridEntryCollection.cs
- DiscoveryOperationContextExtension.cs
- recordstate.cs
- TransformerTypeCollection.cs
- ServiceHttpHandlerFactory.cs
- ObjectMemberMapping.cs
- RankException.cs
- Type.cs
- DecimalAnimation.cs
- Win32Exception.cs
- ShapingEngine.cs
- IndexerNameAttribute.cs
- BinarySerializer.cs
- Nodes.cs
- NameSpaceExtractor.cs
- BindingContext.cs
- DetailsViewInsertEventArgs.cs
- WrapperSecurityCommunicationObject.cs
- MatrixStack.cs
- AdapterDictionary.cs
- ITextView.cs
- TargetException.cs
- SelectionListComponentEditor.cs
- DomNameTable.cs
- TransformationRules.cs
- HighContrastHelper.cs
- AuthStoreRoleProvider.cs
- RowUpdatedEventArgs.cs
- DbSourceCommand.cs
- WebSysDefaultValueAttribute.cs
- ConfigurationElement.cs
- ToolStripInSituService.cs
- ProfileService.cs
- TagPrefixCollection.cs
- LogicalTreeHelper.cs
- JsonReaderWriterFactory.cs
- NamedPipeWorkerProcess.cs
- GridSplitter.cs
- WebPartMinimizeVerb.cs
- TraceData.cs
- DesignerProperties.cs
- PropertyToken.cs
- FontFamily.cs
- GiveFeedbackEvent.cs
- ConstraintStruct.cs
- TabControlDesigner.cs
- updatecommandorderer.cs
- BufferedReadStream.cs
- QueuePropertyVariants.cs
- IDispatchConstantAttribute.cs
- CharacterHit.cs
- SelectionEditor.cs
- XDRSchema.cs
- PerformanceCounterManager.cs
- Line.cs
- MethodAccessException.cs
- SqlResolver.cs
- ShapeTypeface.cs
- Stack.cs
- PaginationProgressEventArgs.cs
- NullableFloatAverageAggregationOperator.cs
- FileDialog_Vista_Interop.cs
- AutoResizedEvent.cs
- QueryCacheKey.cs
- altserialization.cs
- DbgUtil.cs
- DataServiceCollectionOfT.cs
- WinCategoryAttribute.cs
- dbenumerator.cs
- ZoneLinkButton.cs
- SpinWait.cs
- PageFunction.cs
- MenuItemCollection.cs
- WebAdminConfigurationHelper.cs
- EmptyStringExpandableObjectConverter.cs