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
- SplineQuaternionKeyFrame.cs
- DataGrid.cs
- PlainXmlSerializer.cs
- RuntimeIdentifierPropertyAttribute.cs
- BinHexEncoder.cs
- ArrayItemReference.cs
- GuidTagList.cs
- SelectionRangeConverter.cs
- WebPartManagerInternals.cs
- OdbcConnectionHandle.cs
- BamlLocalizationDictionary.cs
- XmlBinaryReaderSession.cs
- SqlLiftWhereClauses.cs
- DefinitionBase.cs
- ObjectHandle.cs
- LocalizableResourceBuilder.cs
- ConfigurationSectionGroup.cs
- AuthenticationService.cs
- PackageRelationshipSelector.cs
- HtmlForm.cs
- PenThreadWorker.cs
- Query.cs
- GlyphTypeface.cs
- DataGridViewRowHeightInfoPushedEventArgs.cs
- XmlHierarchicalEnumerable.cs
- BrushConverter.cs
- XmlAnyElementAttribute.cs
- XmlDataSourceView.cs
- SQLMembershipProvider.cs
- AnnouncementEndpointElement.cs
- UserNameServiceElement.cs
- Message.cs
- AccessText.cs
- GenericAuthenticationEventArgs.cs
- SqlVersion.cs
- Guid.cs
- IntSecurity.cs
- ListControlConvertEventArgs.cs
- CancelEventArgs.cs
- DrawingGroup.cs
- CheckBoxStandardAdapter.cs
- InputMethodStateChangeEventArgs.cs
- ContainerActivationHelper.cs
- PtsPage.cs
- ServiceOperationUIEditor.cs
- XmlSerializerSection.cs
- Storyboard.cs
- CustomDictionarySources.cs
- __Filters.cs
- Debug.cs
- TrackingMemoryStream.cs
- TouchesOverProperty.cs
- XPathSelfQuery.cs
- ProfilePropertyNameValidator.cs
- RecordConverter.cs
- BackoffTimeoutHelper.cs
- SurrogateEncoder.cs
- WebPartDisplayModeEventArgs.cs
- BrowserCapabilitiesFactoryBase.cs
- SqlErrorCollection.cs
- ToolStripSystemRenderer.cs
- CommandBindingCollection.cs
- IriParsingElement.cs
- RecognizedPhrase.cs
- InternalCache.cs
- UInt16Converter.cs
- HtmlToClrEventProxy.cs
- TextStore.cs
- Typography.cs
- HelpEvent.cs
- Resources.Designer.cs
- ResetableIterator.cs
- SchemaImporterExtensionsSection.cs
- MeshGeometry3D.cs
- SynchronizationContext.cs
- GrammarBuilder.cs
- InstanceView.cs
- XmlNodeList.cs
- ButtonRenderer.cs
- TransactionBehavior.cs
- ListItemCollection.cs
- WizardDesigner.cs
- ApplicationBuildProvider.cs
- HttpWebRequestElement.cs
- MenuItemCollection.cs
- DSASignatureFormatter.cs
- TextBoxAutomationPeer.cs
- EmissiveMaterial.cs
- ApplicationGesture.cs
- FtpWebRequest.cs
- AssemblyName.cs
- ChildDocumentBlock.cs
- WorkflowRuntime.cs
- TextEditorParagraphs.cs
- SpeechUI.cs
- SettingsPropertyValueCollection.cs
- WebRequestModuleElement.cs
- HtmlValidationSummaryAdapter.cs
- UpWmlPageAdapter.cs
- ContainerFilterService.cs