Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx40 / System.ServiceModel.Discovery / System / ServiceModel / Discovery / ProbeDuplexAsyncResult.cs / 1305376 / ProbeDuplexAsyncResult.cs
//---------------------------------------------------------------- // Copyright (c) Microsoft Corporation. All rights reserved. //--------------------------------------------------------------- namespace System.ServiceModel.Discovery { using System.Collections.ObjectModel; using System.Diagnostics.CodeAnalysis; using System.Runtime; abstract class ProbeDuplexAsyncResult: AsyncResult { readonly IDiscoveryServiceImplementation discoveryServiceImpl; readonly IMulticastSuppressionImplementation multicastSuppressionImpl; readonly DuplexFindContext findRequest; readonly DiscoveryOperationContext context; readonly TimeoutHelper timeoutHelper; static AsyncCompletion onShouldRedirectFindCompletedCallback = new AsyncCompletion(OnShouldRedirectFindCompleted); static AsyncCompletion onSendProxyAnnouncementsCompletedCallback = new AsyncCompletion(OnSendProxyAnnouncementsCompleted); static AsyncCallback onFindCompletedCallback = Fx.ThunkCallback(new AsyncCallback(OnFindCompleted)); static AsyncCompletion onSendFindResponsesCompletedCallback = new AsyncCompletion(OnSendFindResponsesCompleted); bool isFindCompleted; [Fx.Tag.SynchronizationObject] object findCompletedLock; TResponseChannel responseChannel; Exception findException; [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] protected ProbeDuplexAsyncResult(TProbeMessage probeMessage, IDiscoveryServiceImplementation discoveryServiceImpl, IMulticastSuppressionImplementation multicastSuppressionImpl, AsyncCallback callback, object state) : base(callback, state) { Fx.Assert(probeMessage != null, "The probeMessage must be non null."); Fx.Assert(discoveryServiceImpl != null, "The discoveryServiceImpl must be non null."); this.discoveryServiceImpl = discoveryServiceImpl; this.multicastSuppressionImpl = multicastSuppressionImpl; this.findCompletedLock = new object(); if (!this.Validate(probeMessage)) { this.Complete(true); return; } else { this.context = new DiscoveryOperationContext(OperationContext.Current); this.findRequest = new DuplexFindContext(this.GetFindCriteria(probeMessage), this); this.timeoutHelper = new TimeoutHelper(this.findRequest.Criteria.Duration); this.timeoutHelper.RemainingTime(); this.Process(); } } TResponseChannel ResponseChannel { get { if (this.responseChannel == null) { this.responseChannel = this.context.GetCallbackChannel (); } return this.responseChannel; } } protected virtual bool Validate(TProbeMessage probeMessage) { return (DiscoveryService.EnsureMessageId() && DiscoveryService.EnsureReplyTo() && this.ValidateContent(probeMessage) && this.EnsureNotDuplicate()); } protected abstract bool ValidateContent(TProbeMessage probeMessage); protected abstract FindCriteria GetFindCriteria(TProbeMessage probeMessage); protected abstract IAsyncResult BeginSendFindResponse( TResponseChannel responseChannel, DiscoveryMessageSequence discoveryMessageSequence, EndpointDiscoveryMetadata matchingEndpoint, AsyncCallback callback, object state); protected abstract void EndSendFindResponse(TResponseChannel responseChannel, IAsyncResult result); protected abstract IAsyncResult BeginSendProxyAnnouncement( TResponseChannel responseChannel, DiscoveryMessageSequence discoveryMessageSequence, EndpointDiscoveryMetadata proxyEndpointDiscoveryMetadata, AsyncCallback callback, object state); protected abstract void EndSendProxyAnnouncement(TResponseChannel responseChannel, IAsyncResult result); static bool OnShouldRedirectFindCompleted(IAsyncResult result) { Collection redirectionEndpoints = null; ProbeDuplexAsyncResult thisPtr = (ProbeDuplexAsyncResult )result.AsyncState; if (thisPtr.multicastSuppressionImpl.EndShouldRedirectFind(result, out redirectionEndpoints)) { return thisPtr.SendProxyAnnouncements(redirectionEndpoints); } else { return thisPtr.ProcessFindRequest(); } } static bool OnSendProxyAnnouncementsCompleted(IAsyncResult result) { ProxyAnnouncementsSendAsyncResult.End(result); return true; } static void OnFindCompleted(IAsyncResult result) { if (result.CompletedSynchronously) { return; } else { ProbeDuplexAsyncResult thisPtr = (ProbeDuplexAsyncResult )result.AsyncState; thisPtr.FinishFind(result); } } static bool OnSendFindResponsesCompleted(IAsyncResult result) { FindResponsesSendAsyncResult.End(result); ProbeDuplexAsyncResult thisPtr = (ProbeDuplexAsyncResult )result.AsyncState; if (thisPtr.findException != null) { throw FxTrace.Exception.AsError(thisPtr.findException); } return true; } void FinishFind(IAsyncResult result) { try { lock (this.findCompletedLock) { this.isFindCompleted = true; } this.discoveryServiceImpl.EndFind(result); } catch (Exception e) { if (Fx.IsFatal(e)) { throw; } this.findException = e; } finally { this.findRequest.MatchingEndpoints.Shutdown(); } } void Process() { if ((this.multicastSuppressionImpl != null) && (this.context.DiscoveryMode == ServiceDiscoveryMode.Adhoc)) { if (this.SuppressFindRequest()) { this.Complete(true); return; } } else { if (this.ProcessFindRequest()) { this.Complete(true); return; } } } bool SuppressFindRequest() { IAsyncResult result = this.multicastSuppressionImpl.BeginShouldRedirectFind( this.findRequest.Criteria, this.PrepareAsyncCompletion(onShouldRedirectFindCompletedCallback), this); return (result.CompletedSynchronously && OnShouldRedirectFindCompleted(result)); } bool SendProxyAnnouncements(Collection redirectionEndpoints) { if ((redirectionEndpoints == null) || (redirectionEndpoints.Count == 0)) { return true; } IAsyncResult result = new ProxyAnnouncementsSendAsyncResult( this, redirectionEndpoints, this.PrepareAsyncCompletion(onSendProxyAnnouncementsCompletedCallback), this); return (result.CompletedSynchronously && OnSendProxyAnnouncementsCompleted(result)); } bool ProcessFindRequest() { IAsyncResult result = this.discoveryServiceImpl.BeginFind( findRequest, onFindCompletedCallback, this); if (result.CompletedSynchronously) { this.FinishFind(result); } return this.SendFindResponses(); } bool SendFindResponses() { IAsyncResult result = new FindResponsesSendAsyncResult( this, this.PrepareAsyncCompletion(onSendFindResponsesCompletedCallback), this); return (result.CompletedSynchronously && OnSendFindResponsesCompleted(result)); } bool EnsureNotDuplicate() { bool isDuplicate = this.discoveryServiceImpl.IsDuplicate(OperationContext.Current.IncomingMessageHeaders.MessageId); if (isDuplicate && TD.DuplicateDiscoveryMessageIsEnabled()) { TD.DuplicateDiscoveryMessage( ProtocolStrings.TracingStrings.Probe, OperationContext.Current.IncomingMessageHeaders.MessageId.ToString()); } return !isDuplicate; } IAsyncResult BeginSendFindResponse( EndpointDiscoveryMetadata matchingEndpoint, TimeSpan timeout, AsyncCallback callback, object state) { IAsyncResult result; IContextChannel contextChannel = (IContextChannel)this.ResponseChannel; using (new OperationContextScope(contextChannel)) { this.context.AddressDuplexResponseMessage(OperationContext.Current); contextChannel.OperationTimeout = timeout; result = this.BeginSendFindResponse( this.ResponseChannel, this.discoveryServiceImpl.GetNextMessageSequence(), matchingEndpoint, callback, state); } return result; } void EndSendFindResponse(IAsyncResult result) { this.EndSendFindResponse(this.ResponseChannel, result); } IAsyncResult BeginSendProxyAnnouncement( EndpointDiscoveryMetadata proxyEndpoint, TimeSpan timeout, AsyncCallback callback, object state) { IAsyncResult result; IContextChannel contextChannel = (IContextChannel)this.ResponseChannel; using (new OperationContextScope(contextChannel)) { this.context.AddressDuplexResponseMessage(OperationContext.Current); contextChannel.OperationTimeout = timeout; result = this.BeginSendProxyAnnouncement( this.ResponseChannel, this.discoveryServiceImpl.GetNextMessageSequence(), proxyEndpoint, callback, state); } return result; } void EndSendProxyAnnouncement(IAsyncResult result) { this.EndSendProxyAnnouncement(this.ResponseChannel, result); } class ProxyAnnouncementsSendAsyncResult : RandomDelaySendsAsyncResult { ProbeDuplexAsyncResult probeDuplexAsyncResult; Collection redirectionEndpoints; public ProxyAnnouncementsSendAsyncResult( ProbeDuplexAsyncResult probeDuplexAsyncResult, Collection redirectionEndpoints, AsyncCallback callback, object state) : base( redirectionEndpoints.Count, probeDuplexAsyncResult.context.MaxResponseDelay, callback, state) { this.probeDuplexAsyncResult = probeDuplexAsyncResult; this.redirectionEndpoints = redirectionEndpoints; this.Start(this.probeDuplexAsyncResult.timeoutHelper.RemainingTime()); } public static void End(IAsyncResult result) { AsyncResult.End (result); } protected override IAsyncResult OnBeginSend(int index, TimeSpan timeout, AsyncCallback callback, object state) { return this.probeDuplexAsyncResult.BeginSendProxyAnnouncement( this.redirectionEndpoints[index], timeout, callback, state); } protected override void OnEndSend(IAsyncResult result) { this.probeDuplexAsyncResult.EndSendProxyAnnouncement(result); } } class FindResponsesSendAsyncResult : RandomDelayQueuedSendsAsyncResult { readonly ProbeDuplexAsyncResult probeDuplexAsyncResult; public FindResponsesSendAsyncResult( ProbeDuplexAsyncResult probeDuplexAsyncResult, AsyncCallback callback, object state) : base( probeDuplexAsyncResult.context.MaxResponseDelay, probeDuplexAsyncResult.findRequest.MatchingEndpoints, callback, state) { this.probeDuplexAsyncResult = probeDuplexAsyncResult; this.Start(this.probeDuplexAsyncResult.timeoutHelper.RemainingTime()); } public static void End(IAsyncResult result) { AsyncResult.End (result); } protected override IAsyncResult OnBeginSendItem( EndpointDiscoveryMetadata item, TimeSpan timeout, AsyncCallback callback, object state) { return this.probeDuplexAsyncResult.BeginSendFindResponse( item, timeout, callback, state); } protected override void OnEndSendItem(IAsyncResult result) { this.probeDuplexAsyncResult.EndSendFindResponse(result); } } class DuplexFindContext : FindRequestContext { readonly InputQueue matchingEndpoints; readonly ProbeDuplexAsyncResult probeDuplexAsyncResult; public DuplexFindContext(FindCriteria criteria, ProbeDuplexAsyncResult probeDuplexAsyncResult) : base(criteria) { this.matchingEndpoints = new InputQueue (); this.probeDuplexAsyncResult = probeDuplexAsyncResult; } public InputQueue MatchingEndpoints { get { return this.matchingEndpoints; } } protected override void OnAddMatchingEndpoint(EndpointDiscoveryMetadata matchingEndpoint) { lock (this.probeDuplexAsyncResult.findCompletedLock) { if (this.probeDuplexAsyncResult.isFindCompleted) { throw FxTrace.Exception.AsError( new InvalidOperationException(SR.DiscoveryCannotAddMatchingEndpoint)); } else { this.matchingEndpoints.EnqueueAndDispatch(matchingEndpoint, null, false); } } } } } } // 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
- HtmlElement.cs
- LinqDataSourceSelectEventArgs.cs
- SecurityChannel.cs
- NavigatingCancelEventArgs.cs
- XmlReflectionImporter.cs
- DataGridTablesFactory.cs
- ISFTagAndGuidCache.cs
- dataprotectionpermissionattribute.cs
- EnumDataContract.cs
- ClearTypeHintValidation.cs
- NullableIntMinMaxAggregationOperator.cs
- ICspAsymmetricAlgorithm.cs
- Accessible.cs
- HwndSourceParameters.cs
- CheckBoxDesigner.cs
- InvalidateEvent.cs
- FilterElement.cs
- NavigationHelper.cs
- PartialCachingAttribute.cs
- UnsafeNativeMethodsMilCoreApi.cs
- SpecularMaterial.cs
- PeerName.cs
- MobileResource.cs
- EventSinkHelperWriter.cs
- ResourceProperty.cs
- SharedStatics.cs
- EmptyCollection.cs
- CapabilitiesRule.cs
- CurrentChangedEventManager.cs
- CodeCompileUnit.cs
- ReadonlyMessageFilter.cs
- SqlMethods.cs
- BitmapMetadataEnumerator.cs
- ComponentResourceKey.cs
- FactoryId.cs
- DataGridAutoGeneratingColumnEventArgs.cs
- UInt16Storage.cs
- CheckStoreFileValidityRequest.cs
- BufferedGraphicsManager.cs
- ParseNumbers.cs
- SurrogateEncoder.cs
- BrowserCapabilitiesCompiler.cs
- FixedBufferAttribute.cs
- OptimisticConcurrencyException.cs
- HighlightVisual.cs
- UnmanagedMemoryStreamWrapper.cs
- MatrixTransform.cs
- InternalUserCancelledException.cs
- StringConverter.cs
- LogWriteRestartAreaState.cs
- DesignerView.xaml.cs
- RoamingStoreFile.cs
- TabOrder.cs
- FusionWrap.cs
- EDesignUtil.cs
- SecurityUtils.cs
- complextypematerializer.cs
- ButtonStandardAdapter.cs
- EdmProperty.cs
- TextEditorCharacters.cs
- FilePrompt.cs
- AppearanceEditorPart.cs
- ColorBuilder.cs
- ZipIOCentralDirectoryBlock.cs
- FastEncoder.cs
- X509Chain.cs
- ShaderEffect.cs
- ResourceKey.cs
- WebPartDeleteVerb.cs
- Delay.cs
- TreeViewBindingsEditorForm.cs
- PrintingPermission.cs
- SourceLineInfo.cs
- Helpers.cs
- HandleCollector.cs
- PtsHost.cs
- PointConverter.cs
- FixedFlowMap.cs
- LinqMaximalSubtreeNominator.cs
- DependencyPropertyChangedEventArgs.cs
- BindValidator.cs
- TemplateBuilder.cs
- TemplateControlBuildProvider.cs
- PeerInvitationResponse.cs
- VisualTreeHelper.cs
- JsonGlobals.cs
- ErrorFormatterPage.cs
- AuthenticateEventArgs.cs
- NewArray.cs
- LassoSelectionBehavior.cs
- FilteredSchemaElementLookUpTable.cs
- ADConnectionHelper.cs
- Camera.cs
- newitemfactory.cs
- ObjectViewFactory.cs
- XmlSchemaSequence.cs
- SupportingTokenParameters.cs
- TransactionScope.cs
- Property.cs
- ArraySegment.cs