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
- Quaternion.cs
- FilePrompt.cs
- ExpressionStringBuilder.cs
- GroupQuery.cs
- safemediahandle.cs
- CopyNodeSetAction.cs
- WebReferencesBuildProvider.cs
- DynamicPropertyHolder.cs
- XhtmlTextWriter.cs
- ToolStripRenderer.cs
- LinqDataSourceEditData.cs
- DeploymentExceptionMapper.cs
- RotateTransform.cs
- ExtenderControl.cs
- JoinSymbol.cs
- BitmapPalettes.cs
- PolicyFactory.cs
- TreeViewHitTestInfo.cs
- OleDbReferenceCollection.cs
- XPathDocument.cs
- Renderer.cs
- ExceptionUtil.cs
- RegionData.cs
- SR.cs
- XPathException.cs
- ListItemCollection.cs
- Int16Animation.cs
- TypeContext.cs
- AddInProcess.cs
- ComponentDispatcherThread.cs
- FormCollection.cs
- RelatedCurrencyManager.cs
- BinaryFormatterWriter.cs
- EmptyEnumerator.cs
- ButtonBase.cs
- TimeSpanSecondsOrInfiniteConverter.cs
- IssuanceLicense.cs
- FlowDocumentView.cs
- OpenTypeCommon.cs
- SupportsEventValidationAttribute.cs
- NetCodeGroup.cs
- FixedSOMPage.cs
- WmlCommandAdapter.cs
- SqlServer2KCompatibilityCheck.cs
- PseudoWebRequest.cs
- ProxyElement.cs
- MessagePartSpecification.cs
- FileSecurity.cs
- SqlDataSourceFilteringEventArgs.cs
- WebPartConnectionsConnectVerb.cs
- SqlBulkCopyColumnMappingCollection.cs
- WbmpConverter.cs
- SerializerWriterEventHandlers.cs
- XmlSchemaAny.cs
- TextEvent.cs
- Equal.cs
- ElementHostAutomationPeer.cs
- TimeoutHelper.cs
- QuaternionValueSerializer.cs
- EntityDataSourceStatementEditor.cs
- LambdaCompiler.Binary.cs
- HtmlTableCell.cs
- DrawingCollection.cs
- RoleExceptions.cs
- SiteMapNodeItemEventArgs.cs
- TextAutomationPeer.cs
- SelectionEditingBehavior.cs
- CompilerLocalReference.cs
- VersionConverter.cs
- GridItemPattern.cs
- SecurityHelper.cs
- SchemaType.cs
- ToolboxService.cs
- RouteUrlExpressionBuilder.cs
- ListCollectionView.cs
- DetailsViewPageEventArgs.cs
- PopupEventArgs.cs
- ColorComboBox.cs
- ObjectStateEntryDbDataRecord.cs
- MsmqTransportSecurity.cs
- InkSerializer.cs
- Mouse.cs
- XmlHierarchicalEnumerable.cs
- WsatServiceCertificate.cs
- _FtpControlStream.cs
- ComPlusAuthorization.cs
- PrintPreviewControl.cs
- IPAddress.cs
- AutoGeneratedFieldProperties.cs
- XPathCompileException.cs
- RoleManagerSection.cs
- HelpProvider.cs
- SolidBrush.cs
- VirtualDirectoryMapping.cs
- TextRangeAdaptor.cs
- x509utils.cs
- Query.cs
- CellNormalizer.cs
- User.cs
- Padding.cs