Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Channels / ConnectionPool.cs / 1 / ConnectionPool.cs
//---------------------------------------------------------------------------- // Copyright (c) Microsoft Corporation. All rights reserved. //--------------------------------------------------------------------------- namespace System.ServiceModel.Channels { using System.Diagnostics; using System.ServiceModel; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.ServiceModel.Diagnostics; using System.Threading; // code that pools items and closes/aborts them as necessary. // shared by IConnection and IChannel users abstract class CommunicationPoolwhere TKey : class where TItem : class { Dictionary endpointPools; int maxCount; int openCount; // need to make sure we prune over a certain number of endpoint pools int pruneAccrual; const int pruneThreshold = 30; protected CommunicationPool(int maxCount) { this.maxCount = maxCount; this.endpointPools = new Dictionary (); this.openCount = 1; } public int MaxIdleConnectionPoolCount { get { return this.maxCount; } } protected object ThisLock { get { return this; } } protected abstract void AbortItem(TItem item); protected abstract void CloseItem(TItem item, TimeSpan timeout); protected abstract TKey GetPoolKey(EndpointAddress address, Uri via); protected virtual EndpointConnectionPool CreateEndpointConnectionPool(TKey key) { return new EndpointConnectionPool(this, key); } public bool Close(TimeSpan timeout) { lock (ThisLock) { if (openCount <= 0) { return true; } openCount--; if (openCount == 0) { this.OnClose(timeout); return true; } return false; } } List PruneIfNecessary() { List itemsToClose = null; pruneAccrual++; if (pruneAccrual > pruneThreshold) { pruneAccrual = 0; itemsToClose = new List (); // first prune the connection pool contents foreach (EndpointConnectionPool pool in endpointPools.Values) { pool.Prune(itemsToClose); } // figure out which connection pools are now empty List endpointKeysToRemove = null; foreach (KeyValuePair poolEntry in endpointPools) { if (poolEntry.Value.CloseIfEmpty()) { if (endpointKeysToRemove == null) { endpointKeysToRemove = new List (); } endpointKeysToRemove.Add(poolEntry.Key); } } // and then prune the connection pools themselves if (endpointKeysToRemove != null) { for (int i = 0; i < endpointKeysToRemove.Count; i++) { endpointPools.Remove(endpointKeysToRemove[i]); } } } return itemsToClose; } EndpointConnectionPool GetEndpointPool(TKey key, TimeSpan timeout) { EndpointConnectionPool result = null; List itemsToClose = null; lock (ThisLock) { if (!endpointPools.TryGetValue(key, out result)) { itemsToClose = PruneIfNecessary(); result = CreateEndpointConnectionPool(key); endpointPools.Add(key, result); } } DiagnosticUtility.DebugAssert(result != null, "EndpointPool must be non-null at this point"); if (itemsToClose != null && itemsToClose.Count > 0) { // allocate half the remaining timeout for our graceful shutdowns TimeoutHelper timeoutHelper = new TimeoutHelper(TimeoutHelper.Divide(timeout, 2)); for (int i = 0; i < itemsToClose.Count; i++) { result.CloseIdleConnection(itemsToClose[i], timeoutHelper.RemainingTime()); } } return result; } public bool TryOpen() { lock (ThisLock) { if (openCount <= 0) { // can't reopen connection pools since the registry purges them on close return false; } else { openCount++; return true; } } } protected virtual void OnClosed() { } void OnClose(TimeSpan timeout) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); foreach (EndpointConnectionPool pool in endpointPools.Values) { try { pool.Close(timeoutHelper.RemainingTime()); } catch (CommunicationException exception) { if (DiagnosticUtility.ShouldTraceError) { TraceUtility.TraceEvent(TraceEventType.Error, TraceCode.ConnectionPoolCloseException, this, exception); } } catch (TimeoutException exception) { if (DiagnosticUtility.ShouldTraceError) { TraceUtility.TraceEvent(TraceEventType.Error, TraceCode.ConnectionPoolCloseException, this, exception); } } } endpointPools.Clear(); } public void AddConnection(TKey key, TItem connection, TimeSpan timeout) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); EndpointConnectionPool endpointPool = GetEndpointPool(key, timeoutHelper.RemainingTime()); endpointPool.AddConnection(connection, timeoutHelper.RemainingTime()); } public TItem TakeConnection(EndpointAddress address, Uri via, TimeSpan timeout, out TKey key) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); key = this.GetPoolKey(address, via); EndpointConnectionPool endpointPool = GetEndpointPool(key, timeoutHelper.RemainingTime()); return endpointPool.TakeConnection(timeoutHelper.RemainingTime()); } public void ReturnConnection(TKey key, TItem connection, bool connectionIsStillGood, TimeSpan timeout) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); EndpointConnectionPool endpointPool = GetEndpointPool(key, timeoutHelper.RemainingTime()); endpointPool.ReturnConnection(connection, connectionIsStillGood, timeoutHelper.RemainingTime()); } // base class for our collection of Idle connections protected abstract class IdleConnectionPool { public abstract int Count { get; } public abstract bool Add(TItem item); public abstract bool Return(TItem item); public abstract TItem Take(out bool closeItem); } protected class EndpointConnectionPool { TKey key; List busyConnections; bool closed; IdleConnectionPool idleConnections; CommunicationPool parent; public EndpointConnectionPool(CommunicationPool parent, TKey key) { this.key = key; this.parent = parent; this.busyConnections = new List (); } protected TKey Key { get { return this.key; } } IdleConnectionPool IdleConnections { get { if (idleConnections == null) { idleConnections = GetIdleConnectionPool(); } return idleConnections; } } protected CommunicationPool Parent { get { return this.parent; } } protected object ThisLock { get { return this; } } // close down the pool if empty public bool CloseIfEmpty() { lock (ThisLock) { if (!closed) { if (busyConnections.Count > 0) { return false; } if (idleConnections != null && idleConnections.Count > 0) { return false; } closed = true; } } return true; } protected virtual void AbortItem(TItem item) { parent.AbortItem(item); } protected virtual void CloseItem(TItem item, TimeSpan timeout) { parent.CloseItem(item, timeout); } public void Abort() { if (closed) { return; } List idleItemsToClose = null; lock (ThisLock) { if (closed) return; closed = true; idleItemsToClose = SnapshotIdleConnections(); } AbortConnections(idleItemsToClose); } public void Close(TimeSpan timeout) { List itemsToClose = null; lock (ThisLock) { if (closed) return; closed = true; itemsToClose = SnapshotIdleConnections(); } try { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); for (int i = 0; i < itemsToClose.Count; i++) { this.CloseItem(itemsToClose[i], timeoutHelper.RemainingTime()); } itemsToClose.Clear(); } finally { AbortConnections(itemsToClose); } } void AbortConnections(List idleItemsToClose) { for (int i = 0; i < idleItemsToClose.Count; i++) { this.AbortItem(idleItemsToClose[i]); } for (int i = 0; i < busyConnections.Count; i++) { this.AbortItem(busyConnections[i]); } busyConnections.Clear(); } // must call under lock (ThisLock) since we are calling IdleConnections.Take() List SnapshotIdleConnections() { List itemsToClose = new List (); bool dummy; for (; ; ) { TItem item = IdleConnections.Take(out dummy); if (item == null) break; itemsToClose.Add(item); } return itemsToClose; } public void AddConnection(TItem connection, TimeSpan timeout) { bool closeConnection = false; lock (ThisLock) { if (!closed) { if (!IdleConnections.Add(connection)) { closeConnection = true; } } else { closeConnection = true; } } if (closeConnection) { try { this.CloseItem(connection, timeout); } catch (CommunicationException e) { if (DiagnosticUtility.ShouldTraceInformation) { DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Information); } this.AbortItem(connection); } } } protected virtual IdleConnectionPool GetIdleConnectionPool() { return new PoolIdleConnectionPool(parent.MaxIdleConnectionPoolCount); } public virtual void Prune(List itemsToClose) { } public TItem TakeConnection(TimeSpan timeout) { TItem item = null; List itemsToClose = null; lock (ThisLock) { if (closed) return null; bool closeItem; while (true) { item = IdleConnections.Take(out closeItem); if (item == null) { break; } if (!closeItem) { busyConnections.Add(item); break; } if (itemsToClose == null) { itemsToClose = new List (); } itemsToClose.Add(item); } } // cleanup any stale items accrued from IdleConnections if (itemsToClose != null) { // and only allocate half the timeout passed in for our graceful shutdowns TimeoutHelper timeoutHelper = new TimeoutHelper(TimeoutHelper.Divide(timeout, 2)); for (int i = 0; i < itemsToClose.Count; i++) { CloseIdleConnection(itemsToClose[i], timeoutHelper.RemainingTime()); } } return item; } public void ReturnConnection(TItem connection, bool connectionIsStillGood, TimeSpan timeout) { bool closeConnection = false; bool abortConnection = false; lock (ThisLock) { if (!closed) { if (busyConnections.Remove(connection) && connectionIsStillGood) { if (!IdleConnections.Return(connection)) { closeConnection = true; } } else { abortConnection = true; } } else { abortConnection = true; } } if (closeConnection) { CloseIdleConnection(connection, timeout); } else if (abortConnection) { this.AbortItem(connection); OnConnectionAborted(); } } public void CloseIdleConnection(TItem connection, TimeSpan timeout) { bool throwing = true; try { this.CloseItem(connection, timeout); throwing = false; } catch (CommunicationException e) { if (DiagnosticUtility.ShouldTraceInformation) { DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Information); } } catch (TimeoutException e) { if (DiagnosticUtility.ShouldTraceInformation) { DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Information); } } finally { if (throwing) { this.AbortItem(connection); } } } protected virtual void OnConnectionAborted() { } protected class PoolIdleConnectionPool : IdleConnectionPool { Pool idleConnections; int maxCount; public PoolIdleConnectionPool(int maxCount) { this.idleConnections = new Pool (maxCount); this.maxCount = maxCount; } public override int Count { get { return idleConnections.Count; } } public override bool Add(TItem connection) { return ReturnToPool(connection); } public override bool Return(TItem connection) { return ReturnToPool(connection); } bool ReturnToPool(TItem connection) { bool result = this.idleConnections.Return(connection); if (!result && DiagnosticUtility.ShouldTraceInformation) { DiagnosticUtility.DiagnosticTrace.TraceEvent(TraceEventType.Information, TraceCode.ConnectionPoolMaxOutboundConnectionsPerEndpointQuotaReached, SR.GetString(SR.TraceCodeConnectionPoolMaxOutboundConnectionsPerEndpointQuotaReached, maxCount), null, null, this); } return result; } public override TItem Take(out bool closeItem) { closeItem = false; return this.idleConnections.Take(); } } } } // all our connection pools support Idling out of connections and lease timeout // (though Named Pipes doesn't leverage the lease timeout) abstract class ConnectionPool : IdlingCommunicationPool { int connectionBufferSize; TimeSpan maxOutputDelay; string name; protected ConnectionPool(IConnectionOrientedTransportChannelFactorySettings settings, TimeSpan leaseTimeout) : base(settings.MaxOutboundConnectionsPerEndpoint, settings.IdleTimeout, leaseTimeout) { this.connectionBufferSize = settings.ConnectionBufferSize; this.maxOutputDelay = settings.MaxOutputDelay; this.name = settings.ConnectionPoolGroupName; } public string Name { get { return this.name; } } protected override void AbortItem(IConnection item) { item.Abort(); } protected override void CloseItem(IConnection item, TimeSpan timeout) { item.Close(timeout); } public virtual bool IsCompatible(IConnectionOrientedTransportChannelFactorySettings settings) { return ( (this.name == settings.ConnectionPoolGroupName) && (this.connectionBufferSize == settings.ConnectionBufferSize) && (this.MaxIdleConnectionPoolCount == settings.MaxOutboundConnectionsPerEndpoint) && (this.IdleTimeout == settings.IdleTimeout) && (this.maxOutputDelay == settings.MaxOutputDelay) ); } } // Helper class used to manage the lifetime of a connection relative to its pool. abstract class ConnectionPoolHelper { IConnectionInitiator connectionInitiator; ConnectionPool connectionPool; Uri via; bool closed; // key for rawConnection in the connection pool string connectionKey; // did rawConnection originally come from connectionPool? bool isConnectionFromPool; // the "raw" connection that should be stored in the pool IConnection rawConnection; // the "upgraded" connection built on top of the "raw" connection to be used for I/O IConnection upgradedConnection; public ConnectionPoolHelper(ConnectionPool connectionPool, IConnectionInitiator connectionInitiator, Uri via) { this.connectionInitiator = connectionInitiator; this.connectionPool = connectionPool; this.via = via; } object ThisLock { get { return this; } } protected abstract IConnection AcceptPooledConnection(IConnection connection, ref TimeoutHelper timeoutHelper); protected abstract IAsyncResult BeginAcceptPooledConnection(IConnection connection, ref TimeoutHelper timeoutHelper, AsyncCallback callback, object state); protected abstract IConnection EndAcceptPooledConnection(IAsyncResult result); protected abstract TimeoutException CreateNewConnectionTimeoutException(TimeSpan timeout, TimeoutException innerException); public IAsyncResult BeginEstablishConnection(TimeSpan timeout, AsyncCallback callback, object state) { return new EstablishConnectionAsyncResult(this, timeout, callback, state); } public IConnection EndEstablishConnection(IAsyncResult result) { return EstablishConnectionAsyncResult.End(result); } IConnection TakeConnection(TimeSpan timeout) { return this.connectionPool.TakeConnection(null, this.via, timeout, out this.connectionKey); } public IConnection EstablishConnection(TimeSpan timeout) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); IConnection localRawConnection = null; IConnection localUpgradedConnection = null; bool localIsConnectionFromPool = true; // first try and use a connection from our pool (and use it if we successfully receive an ACK) while (localIsConnectionFromPool) { localRawConnection = this.TakeConnection(timeoutHelper.RemainingTime()); if (localRawConnection == null) { localIsConnectionFromPool = false; } else { bool preambleSuccess = false; try { localUpgradedConnection = AcceptPooledConnection(localRawConnection, ref timeoutHelper); preambleSuccess = true; break; } catch (CommunicationException e) { if (DiagnosticUtility.ShouldTraceInformation) { DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Information); } // CommmunicationException is ok since it was a cached connection of unknown state } catch (TimeoutException e) { if (DiagnosticUtility.ShouldTraceInformation) { DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Information); } // ditto for TimeoutException } finally { if (!preambleSuccess) { if (DiagnosticUtility.ShouldTraceInformation) { DiagnosticUtility.DiagnosticTrace.TraceEvent( TraceEventType.Information, TraceCode.FailedAcceptFromPool, SR.GetString( SR.TraceCodeFailedAcceptFromPool, timeoutHelper.RemainingTime())); } // This cannot throw TimeoutException since isConnectionStillGood is false (doesn't attempt a Close). this.connectionPool.ReturnConnection(connectionKey, localRawConnection, false, TimeSpan.Zero); } } } } // if there isn't anything in the pool, we need to use a new connection if (!localIsConnectionFromPool) { bool success = false; TimeSpan connectTimeout = timeoutHelper.RemainingTime(); try { try { localRawConnection = this.connectionInitiator.Connect(this.via, connectTimeout); } catch (TimeoutException e) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateNewConnectionTimeoutException( connectTimeout, e)); } this.connectionInitiator = null; localUpgradedConnection = AcceptPooledConnection(localRawConnection, ref timeoutHelper); success = true; } finally { if (!success) { connectionKey = null; if (localRawConnection != null) { localRawConnection.Abort(); } } } } SnapshotConnection(localUpgradedConnection, localRawConnection, localIsConnectionFromPool); return localUpgradedConnection; } void SnapshotConnection(IConnection upgradedConnection, IConnection rawConnection, bool isConnectionFromPool) { lock (ThisLock) { if (closed) { upgradedConnection.Abort(); // cleanup our pool if necessary if (isConnectionFromPool) { this.connectionPool.ReturnConnection(this.connectionKey, rawConnection, false, TimeSpan.Zero); } throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new CommunicationObjectAbortedException( SR.GetString(SR.OperationAbortedDuringConnectionEstablishment, this.via))); } else { this.upgradedConnection = upgradedConnection; this.rawConnection = rawConnection; this.isConnectionFromPool = isConnectionFromPool; } } } public void Abort() { ReleaseConnection(true, TimeSpan.Zero); } public void Close(TimeSpan timeout) { ReleaseConnection(false, timeout); } void ReleaseConnection(bool abort, TimeSpan timeout) { string localConnectionKey; IConnection localUpgradedConnection; IConnection localRawConnection; lock (ThisLock) { this.closed = true; localConnectionKey = this.connectionKey; localUpgradedConnection = this.upgradedConnection; localRawConnection = this.rawConnection; this.upgradedConnection = null; this.rawConnection = null; } if (localUpgradedConnection == null) { return; } try { if (this.isConnectionFromPool) { this.connectionPool.ReturnConnection(localConnectionKey, localRawConnection, !abort, timeout); } else { if (abort) { localUpgradedConnection.Abort(); } else { this.connectionPool.AddConnection(localConnectionKey, localRawConnection, timeout); } } } catch (CommunicationException e) { if (DiagnosticUtility.ShouldTraceInformation) { DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Information); } localUpgradedConnection.Abort(); } } class EstablishConnectionAsyncResult : AsyncResult { ConnectionPoolHelper parent; TimeoutHelper timeoutHelper; IConnection currentConnection; IConnection rawConnection; bool newConnection; bool cleanupConnection; TimeSpan connectTimeout; static AsyncCallback onConnect; static AsyncCallback onProcessConnection = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(OnProcessConnection)); public EstablishConnectionAsyncResult(ConnectionPoolHelper parent, TimeSpan timeout, AsyncCallback callback, object state) : base(callback, state) { this.parent = parent; this.timeoutHelper = new TimeoutHelper(timeout); bool success = false; bool completeSelf = false; try { completeSelf = Begin(); success = true; } finally { if (!success) { Cleanup(); } } if (completeSelf) { Cleanup(); base.Complete(true); } } public static IConnection End(IAsyncResult result) { EstablishConnectionAsyncResult thisPtr = AsyncResult.End (result); return thisPtr.currentConnection; } bool Begin() { IConnection connection = parent.TakeConnection(timeoutHelper.RemainingTime()); TrackConnection(connection); // first try and use a connection from our pool bool openingFromPool; if (OpenUsingConnectionPool(out openingFromPool)) { return true; } if (openingFromPool) { return false; } else { // if there isn't anything in the pool, we need to use a new connection return OpenUsingNewConnection(); } } bool OpenUsingConnectionPool(out bool openingFromPool) { openingFromPool = true; while (this.currentConnection != null) { bool snapshotCollection = false; try { if (ProcessConnection()) { snapshotCollection = true; } else { return false; } } catch (CommunicationException e) { if (DiagnosticUtility.ShouldTraceInformation) { DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Information); } // CommunicationException is allowed for cached channels, as the connection // could be stale Cleanup(); // remove residual state } catch (TimeoutException e) { if (DiagnosticUtility.ShouldTraceInformation) { DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Information); } // ditto for TimeoutException Cleanup(); // remove residual state } if (snapshotCollection) // connection succeeded. Snapshot and return { SnapshotConnection(); return true; } // previous connection failed, try again IConnection connection = parent.TakeConnection(timeoutHelper.RemainingTime()); TrackConnection(connection); } openingFromPool = false; return false; } bool OpenUsingNewConnection() { this.newConnection = true; IAsyncResult result; try { this.connectTimeout = timeoutHelper.RemainingTime(); if (onConnect == null) { onConnect = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(OnConnect)); } result = parent.connectionInitiator.BeginConnect( parent.via, this.connectTimeout, onConnect, this); } catch (TimeoutException e) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( parent.CreateNewConnectionTimeoutException(connectTimeout, e)); } if (!result.CompletedSynchronously) { return false; } return HandleConnect(result); } bool HandleConnect(IAsyncResult connectResult) { try { TrackConnection(parent.connectionInitiator.EndConnect(connectResult)); } catch (TimeoutException e) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( parent.CreateNewConnectionTimeoutException(connectTimeout, e)); } if (ProcessConnection()) { // success. Snapshot and return SnapshotConnection(); return true; } else { return false; } } bool ProcessConnection() { IAsyncResult result = parent.BeginAcceptPooledConnection(this.rawConnection, ref timeoutHelper, onProcessConnection, this); if (!result.CompletedSynchronously) { return false; } return HandleProcessConnection(result); } bool HandleProcessConnection(IAsyncResult result) { this.currentConnection = parent.EndAcceptPooledConnection(result); this.cleanupConnection = false; return true; } void SnapshotConnection() { parent.SnapshotConnection(this.currentConnection, this.rawConnection, !this.newConnection); } void TrackConnection(IConnection connection) { this.cleanupConnection = true; this.rawConnection = connection; this.currentConnection = connection; } void Cleanup() { if (this.cleanupConnection) { if (this.newConnection) { if (this.currentConnection != null) { this.currentConnection.Abort(); this.currentConnection = null; } } else if (this.rawConnection != null) { if (DiagnosticUtility.ShouldTraceInformation) { DiagnosticUtility.DiagnosticTrace.TraceEvent( TraceEventType.Information, TraceCode.FailedAcceptFromPool, SR.GetString( SR.TraceCodeFailedAcceptFromPool, this.timeoutHelper.RemainingTime())); } // This cannot throw TimeoutException since isConnectionStillGood is false (doesn't attempt a Close). parent.connectionPool.ReturnConnection(parent.connectionKey, this.rawConnection, false, timeoutHelper.RemainingTime()); this.currentConnection = null; this.rawConnection = null; } this.cleanupConnection = false; } } static void OnConnect(IAsyncResult result) { if (result.CompletedSynchronously) { return; } EstablishConnectionAsyncResult thisPtr = (EstablishConnectionAsyncResult)result.AsyncState; Exception completionException = null; bool completeSelf; try { completeSelf = thisPtr.HandleConnect(result); } #pragma warning suppress 56500 // [....], transferring exception to another thread catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) { throw; } completeSelf = true; completionException = e; } if (completeSelf) { thisPtr.Cleanup(); thisPtr.Complete(false, completionException); } } static void OnProcessConnection(IAsyncResult result) { if (result.CompletedSynchronously) { return; } EstablishConnectionAsyncResult thisPtr = (EstablishConnectionAsyncResult)result.AsyncState; Exception completionException = null; bool completeSelf; try { bool snapshotCollection = false; try { completeSelf = thisPtr.HandleProcessConnection(result); if (completeSelf) { snapshotCollection = true; } } catch (CommunicationException communicationException) { if (!thisPtr.newConnection) // CommunicationException is ok from our cache { if (DiagnosticUtility.ShouldTraceInformation) { DiagnosticUtility.ExceptionUtility.TraceHandledException(communicationException, TraceEventType.Information); } thisPtr.Cleanup(); completeSelf = thisPtr.Begin(); } else { completeSelf = true; completionException = communicationException; } } catch (TimeoutException timeoutException) { if (!thisPtr.newConnection) // TimeoutException is ok from our cache { if (DiagnosticUtility.ShouldTraceInformation) { DiagnosticUtility.ExceptionUtility.TraceHandledException(timeoutException, TraceEventType.Information); } thisPtr.Cleanup(); completeSelf = thisPtr.Begin(); } else { completeSelf = true; completionException = timeoutException; } } if (snapshotCollection) { thisPtr.SnapshotConnection(); } } #pragma warning suppress 56500 // [....], transferring exception to another thread catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) { throw; } completeSelf = true; completionException = e; } if (completeSelf) { thisPtr.Cleanup(); thisPtr.Complete(false, completionException); } } } } } // 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
- DomainConstraint.cs
- SimpleApplicationHost.cs
- BamlRecordReader.cs
- SchemaHelper.cs
- XmlDataDocument.cs
- SAPICategories.cs
- ScalarConstant.cs
- CurrentChangingEventManager.cs
- HashLookup.cs
- RSAOAEPKeyExchangeFormatter.cs
- HierarchicalDataBoundControlAdapter.cs
- TaiwanLunisolarCalendar.cs
- OdbcStatementHandle.cs
- SymbolUsageManager.cs
- Dynamic.cs
- TimeZoneNotFoundException.cs
- DataControlFieldCell.cs
- DocumentStream.cs
- DecryptedHeader.cs
- MainMenu.cs
- GroupItemAutomationPeer.cs
- GridSplitterAutomationPeer.cs
- PropertyPathWorker.cs
- EventDescriptor.cs
- DecoderFallbackWithFailureFlag.cs
- MetadataFile.cs
- HebrewCalendar.cs
- FormViewUpdateEventArgs.cs
- ReferencedCollectionType.cs
- Rect.cs
- InvokeDelegate.cs
- Parameter.cs
- CustomValidator.cs
- JsonEncodingStreamWrapper.cs
- ContentDefinition.cs
- XmlNodeChangedEventManager.cs
- TextEditor.cs
- XslNumber.cs
- CompositeControlDesigner.cs
- ScriptRegistrationManager.cs
- TrustDriver.cs
- IxmlLineInfo.cs
- DateTimeValueSerializerContext.cs
- ConfigurationManagerInternalFactory.cs
- EastAsianLunisolarCalendar.cs
- EncodingTable.cs
- EventLog.cs
- PriorityQueue.cs
- SqlProviderServices.cs
- MexHttpBindingCollectionElement.cs
- SystemIcons.cs
- FontDriver.cs
- AspNetHostingPermission.cs
- mediaeventargs.cs
- RealizationContext.cs
- DataGridViewRowPostPaintEventArgs.cs
- BamlReader.cs
- ReachFixedDocumentSerializerAsync.cs
- __Error.cs
- SoapWriter.cs
- SqlLiftWhereClauses.cs
- IdentityManager.cs
- PrivateFontCollection.cs
- TextEvent.cs
- newitemfactory.cs
- DateTimeFormatInfo.cs
- RuntimeResourceSet.cs
- StickyNoteAnnotations.cs
- HtmlInputPassword.cs
- ZipIORawDataFileBlock.cs
- ManualResetEvent.cs
- XmlArrayAttribute.cs
- RegexReplacement.cs
- VariableQuery.cs
- RelationshipEntry.cs
- PropertyMetadata.cs
- ServiceDurableInstanceContextProvider.cs
- PublisherIdentityPermission.cs
- TextAnchor.cs
- SqlProviderServices.cs
- CodeTypeReference.cs
- CheckPair.cs
- KeyTime.cs
- ComboBox.cs
- ReflectPropertyDescriptor.cs
- SystemWebCachingSectionGroup.cs
- XamlWriter.cs
- SelectingProviderEventArgs.cs
- SchemaContext.cs
- RegistrationServices.cs
- XmlDocumentType.cs
- Win32Native.cs
- GlobalProxySelection.cs
- XmlBufferedByteStreamReader.cs
- TextSelectionHighlightLayer.cs
- ExecutionEngineException.cs
- HttpAsyncResult.cs
- PerformanceCounterPermissionEntry.cs
- SynchronizedDispatch.cs
- HtmlInputRadioButton.cs