Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / ndp / fx / src / Data / System / Data / ProviderBase / DbConnectionInternal.cs / 1 / DbConnectionInternal.cs
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// [....]
//-----------------------------------------------------------------------------
namespace System.Data.ProviderBase {
using System;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using SysTx = System.Transactions;
internal abstract class DbConnectionInternal { // V1.1.3300
private static int _objectTypeCount;
internal readonly int _objectID = Interlocked.Increment(ref _objectTypeCount);
internal static readonly StateChangeEventArgs StateChangeClosed = new StateChangeEventArgs(ConnectionState.Open, ConnectionState.Closed);
internal static readonly StateChangeEventArgs StateChangeOpen = new StateChangeEventArgs(ConnectionState.Closed, ConnectionState.Open);
private readonly bool _allowSetConnectionString;
private readonly bool _hidePassword;
private readonly ConnectionState _state;
private readonly WeakReference _owningObject = new WeakReference(null, false); // [usage must be thread safe] the owning object, when not in the pool. (both Pooled and Non-Pooled connections)
// should only be used by DbConnectionPool.DbConnectionInternalListStack.Synchronized(Push|Pop)
private DbConnectionInternal _nextPooledObject;
internal DbConnectionInternal NextPooledObject {
get { return _nextPooledObject; }
set { _nextPooledObject = value; }
}
private DbConnectionPool _connectionPool; // the pooler that the connection came from (Pooled connections only)
private DbConnectionPoolCounters _performanceCounters; // the performance counters we're supposed to update
private DbReferenceCollection _referenceCollection; // collection of objects that we need to notify in some way when we're being deactivated
private int _pooledCount; // [usage must be thread safe] the number of times this object has been pushed into the pool less the number of times it's been popped (0 != inPool)
private bool _connectionIsDoomed; // true when the connection should no longer be used.
private bool _cannotBePooled; // true when the connection should no longer be pooled.
private bool _isInStasis;
private DateTime _createTime; // when the connection was created.
private SysTx.Transaction _enlistedTransaction; // [usage must be thread-safe] the transaction that we're enlisted in, either manually or automatically
#if DEBUG
private int _activateCount; // debug only counter to verify activate/deactivates are in [....].
#endif //DEBUG
protected DbConnectionInternal() : this(ConnectionState.Open, true, false) { // V1.1.3300
}
// Constructor for internal connections
internal DbConnectionInternal(ConnectionState state, bool hidePassword, bool allowSetConnectionString) {
_allowSetConnectionString = allowSetConnectionString;
_hidePassword = hidePassword;
_state = state;
}
internal bool AllowSetConnectionString {
get {
return _allowSetConnectionString;
}
}
internal bool CanBePooled {
get {
bool flag = (!_connectionIsDoomed && !_cannotBePooled && !_owningObject.IsAlive);
return flag;
}
}
protected internal SysTx.Transaction EnlistedTransaction {
get {
return _enlistedTransaction;
}
set {
if (((null == _enlistedTransaction) && (null != value))
|| ((null != _enlistedTransaction) && !_enlistedTransaction.Equals(value))) { // WebData 20000024
// Pay attention to the order here:
// 1) defect from any notifications
// 2) replace the transaction
// 3) re-enlist in notifications for the new transaction
// SQLBUDT #230558 we need to use a clone of the transaction
// when we store it, or we'll end up keeping it past the
// duration of the using block of the TransactionScope
SysTx.Transaction valueClone = null;
SysTx.Transaction previousTransactionClone = null;
try {
if (null != value) {
valueClone = value.Clone();
}
// NOTE: rather than take locks around several potential round-
// trips to the server, and/or virtual function calls, we simply
// presume that you aren't doing something illegal from multiple
// threads, and check once we get around to finalizing things
// inside a lock.
lock(this) {
// NOTE: There is still a race condition here, when we are
// called from EnlistTransaction (which cannot re-enlist)
// instead of EnlistDistributedTransaction (which can),
// however this should have been handled by the outer
// connection which checks to ensure that it's OK. The
// only case where we have the race condition is multiple
// concurrent enlist requests to the same connection, which
// is a bit out of line with something we should have to
// support.
previousTransactionClone = _enlistedTransaction;
_enlistedTransaction = valueClone;
value = valueClone;
valueClone = null; // we've stored it, don't dispose it.
}
}
finally {
// we really need to dispose our clones; they may have
// native resources and GC may not happen soon enough.
if (null != previousTransactionClone) {
previousTransactionClone.Dispose();
}
if (null != valueClone) {
valueClone.Dispose();
}
}
// I don't believe that we need to lock to protect the actual
// enlistment in the transaction; it would only protect us
// against multiple concurrent calls to enlist, which really
// isn't supported anyway.
if (null != value) {
if (Bid.IsOn(DbConnectionPool.PoolerTracePoints)) {
int x = value.GetHashCode();
Bid.PoolerTrace(" %d#, Transaction %d#, Enlisting.\n", ObjectID, x);
}
TransactionOutcomeEnlist(value);
}
}
}
}
// Is this connection in stasis, waiting for transaction to end before returning to pool?
internal bool IsTxRootWaitingForTxEnd {
get {
return _isInStasis;
}
}
virtual internal bool RequireExplicitTransactionUnbind {
get {
return false; // override to add explicit unbind requirement
}
}
// Is this a connection that must be put in stasis (or is already in stasis) pending the end of it's transaction?
virtual protected internal bool IsNonPoolableTransactionRoot {
get {
return false; // if you want to have delegated transactions that are non-poolable, you better override this...
}
}
virtual internal bool IsTransactionRoot {
get {
return false; // if you want to have delegated transactions, you better override this...
}
}
public bool HasEnlistedTransaction {
get {
return (null != EnlistedTransaction); // NOTE: race condition in EnlistedTransaction applies here too.
}
}
protected internal bool IsConnectionDoomed {
get {
return _connectionIsDoomed;
}
}
internal bool IsEmancipated {
get {
// NOTE: There are race conditions between PrePush, PostPop and this
// property getter -- only use this while this object is locked;
// (DbConnectionPool.Clear and ReclaimEmancipatedObjects
// do this for us)
// Remember how this works (I keep getting confused...)
//
// _pooledCount is incremented when the connection is pushed into the pool
// _pooledCount is decremented when the connection is popped from the pool
// _pooledCount is set to -1 when the connection is not pooled (just in case...)
//
// That means that:
//
// _pooledCount > 1 connection is in the pool multiple times (this is a serious bug...)
// _pooledCount == 1 connection is in the pool
// _pooledCount == 0 connection is out of the pool
// _pooledCount == -1 connection is not a pooled connection; we shouldn't be here for non-pooled connections.
// _pooledCount < -1 connection out of the pool multiple times (not sure how this could happen...)
//
// Now, our job is to return TRUE when the connection is out
// of the pool and it's owning object is no longer around to
// return it.
bool value = !IsTxRootWaitingForTxEnd && (_pooledCount < 1) && !_owningObject.IsAlive;
return value;
}
}
internal int ObjectID {
get {
return _objectID;
}
}
protected internal object Owner {
// We use a weak reference to the owning object so we can identify when
// it has been garbage collected without thowing exceptions.
get {
return _owningObject.Target;
}
}
internal DbConnectionPool Pool {
get {
return _connectionPool;
}
}
protected DbConnectionPoolCounters PerformanceCounters {
get {
return _performanceCounters;
}
}
virtual protected bool ReadyToPrepareTransaction {
get {
return true;
}
}
protected internal DbReferenceCollection ReferenceCollection {
get {
return _referenceCollection;
}
}
abstract public string ServerVersion {
get;
}
// this should be abstract but untill it is added to all the providers virtual will have to do [....]
virtual public string ServerVersionNormalized {
get{
throw ADP.NotSupported();
}
}
public bool ShouldHidePassword {
get {
return _hidePassword;
}
}
public ConnectionState State {
get {
return _state;
}
}
abstract protected void Activate(SysTx.Transaction transaction);
internal void ActivateConnection(SysTx.Transaction transaction) {
// Internal method called from the connection pooler so we don't expose
// the Activate method publicly.
Bid.PoolerTrace(" %d#, Activating\n", ObjectID);
#if DEBUG
int activateCount = Interlocked.Increment(ref _activateCount);
Debug.Assert(1 == activateCount, "activated multiple times?");
#endif // DEBUG
Activate(transaction);
PerformanceCounters.NumberOfActiveConnections.Increment();
}
internal void AddWeakReference(object value, int tag) {
if (null == _referenceCollection) {
_referenceCollection = CreateReferenceCollection();
if (null == _referenceCollection) {
throw ADP.InternalError(ADP.InternalErrorCode.CreateReferenceCollectionReturnedNull);
}
}
_referenceCollection.Add(value, tag);
}
abstract public DbTransaction BeginTransaction(IsolationLevel il);
virtual public void ChangeDatabase(string value) {
throw ADP.MethodNotImplemented("ChangeDatabase");
}
internal virtual void CloseConnection(DbConnection owningObject, DbConnectionFactory connectionFactory) {
// The implementation here is the implementation required for the
// "open" internal connections, since our own private "closed"
// singleton internal connection objects override this method to
// prevent anything funny from happening (like disposing themselves
// or putting them into a connection pool)
//
// Derived class should override DbConnectionInternal.Deactivate and DbConnectionInternal.Dispose
// for cleaning up after DbConnection.Close
// protected override void Deactivate() { // override DbConnectionInternal.Close
// // do derived class connection deactivation for both pooled & non-pooled connections
// }
// public override void Dispose() { // override DbConnectionInternal.Close
// // do derived class cleanup
// base.Dispose();
// }
//
// overriding DbConnection.Close is also possible, but must provider for their own synchronization
// public override void Close() { // override DbConnection.Close
// base.Close();
// // do derived class outer connection for both pooled & non-pooled connections
// // user must do their own synchronization here
// }
//
// if the DbConnectionInternal derived class needs to close the connection it should
// delegate to the DbConnection if one exists or directly call dispose
// DbConnection owningObject = (DbConnection)Owner;
// if (null != owningObject) {
// owningObject.Close(); // force the closed state on the outer object.
// }
// else {
// Dispose();
// }
//
////////////////////////////////////////////////////////////////
// DON'T MESS WITH THIS CODE UNLESS YOU KNOW WHAT YOU'RE DOING!
////////////////////////////////////////////////////////////////
Debug.Assert(null != owningObject, "null owningObject");
Debug.Assert(null != connectionFactory, "null connectionFactory");
Debug.Assert(owningObject == Owner, "Close with different owner");
Debug.Assert(connectionFactory.GetInnerConnection(owningObject) == this || this.IsConnectionDoomed, "Close of not this");
Bid.PoolerTrace(" %d# Closing.\n", ObjectID);
// if an exception occurs after the state change but before the try block
// the connection will be stuck in OpenBusy state. The commented out try-catch
// block doesn't really help because a ThreadAbort during the finally block
// would just refert the connection to a bad state.
// Open->Closed: guarantee internal connection is returned to correct pool
if (connectionFactory.SetInnerConnectionFrom(owningObject, DbConnectionOpenBusy.SingletonInstance, this)) {
try {
DbConnectionPool connectionPool = Pool;
// Detach from enlisted transactions that are no longer active on close
SysTx.Transaction enlistedTransaction = EnlistedTransaction;
if (null != enlistedTransaction && SysTx.TransactionStatus.Active != enlistedTransaction.TransactionInformation.Status) {
DetachTransaction(enlistedTransaction);
}
// The singleton closed classes won't have owners and
// connection pools, and we won't want to put them back
// into the pool.
if (null != connectionPool) {
connectionPool.PutObject(this, owningObject); // PutObject calls Deactivate for us...
// NOTE: Before we leave the PutObject call, another
// thread may have already popped the connection from
// the pool, so don't expect to be able to verify it.
}
else {
Deactivate(); // ensure we de-activate non-pooled connections, or the data readers and transactions may not get cleaned up...
PerformanceCounters.HardDisconnectsPerSecond.Increment();
// To prevent an endless recursion, we need to clear
// the owning object before we call dispose so that
// we can't get here a second time... Ordinarily, I
// would call setting the owner to null a hack, but
// this is safe since we're about to dispose the
// object and it won't have an owner after that for
// certain.
_owningObject.Target = null;
if (IsTransactionRoot) {
SetInStasis();
}
else {
PerformanceCounters.NumberOfNonPooledConnections.Decrement();
#if !ORACLE
if (this.GetType() != typeof(System.Data.SqlClient.SqlInternalConnectionSmi))
#endif
{
Dispose();
}
}
}
}
finally {
// if a ThreadAbort puts us here then its possible the outer connection will not reference
// this and this will be orphaned, not reclaimed by object pool until outer connection goes out of scope.
connectionFactory.SetInnerConnectionEvent(owningObject, DbConnectionClosedPreviouslyOpened.SingletonInstance);
}
}
}
virtual protected DbReferenceCollection CreateReferenceCollection() {
throw ADP.InternalError(ADP.InternalErrorCode.AttemptingToConstructReferenceCollectionOnStaticObject);
}
abstract protected void Deactivate();
internal void DeactivateConnection() {
// Internal method called from the connection pooler so we don't expose
// the Deactivate method publicly.
Bid.PoolerTrace(" %d#, Deactivating\n", ObjectID);
#if DEBUG
int activateCount = Interlocked.Decrement(ref _activateCount);
Debug.Assert(0 == activateCount, "activated multiple times?");
#endif // DEBUG
PerformanceCounters.NumberOfActiveConnections.Decrement();
if (!_connectionIsDoomed && Pool.UseLoadBalancing) {
// If we're not already doomed, check the connection's lifetime and
// doom it if it's lifetime has elapsed.
DateTime now = DateTime.UtcNow; // WebData 111116
if ((now.Ticks - _createTime.Ticks) > Pool.LoadBalanceTimeout.Ticks) {
DoNotPoolThisConnection();
}
}
Deactivate();
}
virtual internal void DelegatedTransactionEnded() {
// Called by System.Transactions when the delegated transaction has
// completed. We need to make closed connections that are in stasis
// available again, or disposed closed/leaked non-pooled connections.
// IMPORTANT NOTE: You must have taken a lock on the object before
// you call this method to prevent race conditions with Clear and
// ReclaimEmancipatedObjects.
Bid.Trace(" %d#, Delegated Transaction Completed.\n", ObjectID);
if (1 == _pooledCount) {
// When _pooledCount is 1, it indicates a closed, pooled,
// connection so it is ready to put back into the pool for
// general use.
TerminateStasis(true);
Deactivate(); // call it one more time just in case
DbConnectionPool pool = Pool;
if (null == pool) {
throw ADP.InternalError(ADP.InternalErrorCode.PooledObjectWithoutPool); // pooled connection does not have a pool
}
pool.PutObjectFromTransactedPool(this);
}
else if (-1 == _pooledCount && !_owningObject.IsAlive) {
// When _pooledCount is -1 and the owning object no longer exists,
// it indicates a closed (or leaked), non-pooled connection so
// it is safe to dispose.
TerminateStasis(false);
Deactivate(); // call it one more time just in case
// it's a non-pooled connection, we need to dispose of it
// once and for all, or the server will have fits about us
// leaving connections open until the client-side GC kicks
// in.
PerformanceCounters.NumberOfNonPooledConnections.Decrement();
Dispose();
}
// When _pooledCount is 0, the connection is a pooled connection
// that is either open (if the owning object is alive) or leaked (if
// the owning object is not alive) In either case, we can't muck
// with the connection here.
}
public virtual void Dispose() {
_connectionPool = null;
_performanceCounters = null;
_connectionIsDoomed = true;
_enlistedTransaction = null; //
}
protected internal void DoNotPoolThisConnection() {
_cannotBePooled = true;
Bid.PoolerTrace(" %d#, Marking pooled object as non-poolable so it will be disposed\n", ObjectID);
}
/// Ensure that this connection cannot be put back into the pool.
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
protected internal void DoomThisConnection() {
_connectionIsDoomed = true;
Bid.PoolerTrace(" %d#, Dooming\n", ObjectID);
}
abstract public void EnlistTransaction(SysTx.Transaction transaction);
virtual protected internal DataTable GetSchema(DbConnectionFactory factory, DbConnectionPoolGroup poolGroup, DbConnection outerConnection, string collectionName, string[] restrictions){
Debug.Assert(outerConnection != null,"outerConnection may not be null.");
DbMetaDataFactory metaDataFactory = factory.GetMetaDataFactory(poolGroup, this);
Debug.Assert(metaDataFactory != null,"metaDataFactory may not be null.");
return metaDataFactory.GetSchema(outerConnection, collectionName,restrictions);
}
internal void MakeNonPooledObject(object owningObject, DbConnectionPoolCounters performanceCounters) {
// Used by DbConnectionFactory to indicate that this object IS NOT part of
// a connection pool.
_connectionPool = null;
_performanceCounters = performanceCounters;
_owningObject.Target = owningObject;
_pooledCount = -1;
}
internal void MakePooledConnection(DbConnectionPool connectionPool) {
// Used by DbConnectionFactory to indicate that this object IS part of
// a connection pool.
//
_createTime = DateTime.UtcNow; // WebData 111116
_connectionPool = connectionPool;
_performanceCounters = connectionPool.PerformanceCounters;
}
internal void NotifyWeakReference(int message) {
DbReferenceCollection referenceCollection = ReferenceCollection;
if (null != referenceCollection) {
referenceCollection.Notify(message);
}
}
/// The default implementation is for the open connection objects, and
/// it simply throws. Our private closed-state connection objects
/// override this and do the correct thing.
// User code should either override DbConnectionInternal.Activate when it comes out of the pool
// or override DbConnectionFactory.CreateConnection when the connection is created for non-pooled connections
internal virtual void OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory) {
throw ADP.ConnectionAlreadyOpen(State);
}
internal void PrePush(object expectedOwner) {
// Called by DbConnectionPool when we're about to be put into it's pool, we
// take this opportunity to ensure ownership and pool counts are legit.
// IMPORTANT NOTE: You must have taken a lock on the object before
// you call this method to prevent race conditions with Clear and
// ReclaimEmancipatedObjects.
//3 // The following tests are retail assertions of things we can't allow to happen.
if (null == expectedOwner) {
if (null != _owningObject.Target) {
throw ADP.InternalError(ADP.InternalErrorCode.UnpooledObjectHasOwner); // new unpooled object has an owner
}
}
else if (_owningObject.Target != expectedOwner) {
throw ADP.InternalError(ADP.InternalErrorCode.UnpooledObjectHasWrongOwner); // unpooled object has incorrect owner
}
if (0 != _pooledCount) {
throw ADP.InternalError(ADP.InternalErrorCode.PushingObjectSecondTime); // pushing object onto stack a second time
}
if (Bid.IsOn(DbConnectionPool.PoolerTracePoints)) {
//DbConnection x = (expectedOwner as DbConnection);
Bid.PoolerTrace(" %d#, Preparing to push into pool, owning connection %d#, pooledCount=%d\n", ObjectID, 0, _pooledCount);
}
_pooledCount++;
_owningObject.Target = null; // NOTE: doing this and checking for InternalError.PooledObjectHasOwner degrades the close by 2%
}
internal void PostPop(object newOwner) {
// Called by DbConnectionPool right after it pulls this from it's pool, we
// take this opportunity to ensure ownership and pool counts are legit.
Debug.Assert(!IsEmancipated,"pooled object not in pool");
// SQLBUDT #356871 -- When another thread is clearing this pool, it
// will doom all connections in this pool without prejudice which
// causes the following assert to fire, which really mucks up stress
// against checked bits. The assert is benign, so we're commenting
// it out.
//Debug.Assert(CanBePooled, "pooled object is not poolable");
// IMPORTANT NOTE: You must have taken a lock on the object before
// you call this method to prevent race conditions with Clear and
// ReclaimEmancipatedObjects.
if (null != _owningObject.Target) {
throw ADP.InternalError(ADP.InternalErrorCode.PooledObjectHasOwner); // pooled connection already has an owner!
}
_owningObject.Target = newOwner;
_pooledCount--;
if (Bid.IsOn(DbConnectionPool.PoolerTracePoints)) {
//DbConnection x = (newOwner as DbConnection);
Bid.PoolerTrace(" %d#, Preparing to pop from pool, owning connection %d#, pooledCount=%d\n", ObjectID, 0, _pooledCount);
}
//3 // The following tests are retail assertions of things we can't allow to happen.
if (null != Pool) {
if (0 != _pooledCount) {
throw ADP.InternalError(ADP.InternalErrorCode.PooledObjectInPoolMoreThanOnce); // popping object off stack with multiple pooledCount
}
}
else if (-1 != _pooledCount) {
throw ADP.InternalError(ADP.InternalErrorCode.NonPooledObjectUsedMoreThanOnce); // popping object off stack with multiple pooledCount
}
}
internal void RemoveWeakReference(object value) {
DbReferenceCollection referenceCollection = ReferenceCollection;
if (null != referenceCollection) {
referenceCollection.Remove(value);
}
}
// Cleanup connection's transaction-specific structures (currently used by Delegated transaction).
// This is a separate method because cleanup can be triggered in multiple ways for a delegated
// transaction.
virtual protected void CleanupTransactionOnCompletion(SysTx.Transaction transaction) {
}
// Detach transaction from connection.
internal void DetachTransaction(SysTx.Transaction transaction) {
Bid.Trace(" %d#, Transaction Completed. (pooledCount=%d)\n", ObjectID, _pooledCount);
// potentially a multi-threaded event, so lock the connection to make sure we don't enlist in a new
// transaction between compare and assignment. No need to short circuit outside of lock, since failed comparisons should
// be the exception, not the rule.
lock (this) {
// Detach if detach-on-end behavior, or if outer connection was closed
DbConnection owner = (DbConnection)Owner;
if (!RequireExplicitTransactionUnbind || null == owner) {
if (_enlistedTransaction != null && transaction.Equals(_enlistedTransaction)) {
EnlistedTransaction = null;
if (IsTxRootWaitingForTxEnd) {
DelegatedTransactionEnded();
}
}
}
}
}
// Handle transaction detach, pool cleanup and other post-transaction cleanup tasks associated with
internal void CleanupConnectionOnTransactionCompletion(SysTx.Transaction transaction) {
DetachTransaction(transaction);
DbConnectionPool pool = Pool;
if (null != pool) {
pool.TransactionEnded(transaction, this);
}
}
void TransactionCompletedEvent(object sender, SysTx.TransactionEventArgs e) {
SysTx.Transaction transaction = e.Transaction;
Bid.Trace(" %d#, Transaction Completed. (pooledCount=%d)\n", ObjectID, _pooledCount);
CleanupTransactionOnCompletion(transaction);
CleanupConnectionOnTransactionCompletion(transaction);
}
//
[SecurityPermission(SecurityAction.Assert, Flags=SecurityPermissionFlag.UnmanagedCode)]
private void TransactionOutcomeEnlist(SysTx.Transaction transaction) {
transaction.TransactionCompleted += new SysTx.TransactionCompletedEventHandler(TransactionCompletedEvent);
}
internal void SetInStasis() {
_isInStasis = true;
Bid.PoolerTrace(" %d#, Non-Pooled Connection has Delegated Transaction, waiting to Dispose.\n", ObjectID);
PerformanceCounters.NumberOfStasisConnections.Increment();
}
private void TerminateStasis(bool returningToPool) {
if (returningToPool) {
Bid.PoolerTrace(" %d#, Delegated Transaction has ended, connection is closed. Returning to general pool.\n", ObjectID);
}
else {
Bid.PoolerTrace(" %d#, Delegated Transaction has ended, connection is closed/leaked. Disposing.\n", ObjectID);
}
PerformanceCounters.NumberOfStasisConnections.Decrement();
_isInStasis = false;
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// [....]
//-----------------------------------------------------------------------------
namespace System.Data.ProviderBase {
using System;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using SysTx = System.Transactions;
internal abstract class DbConnectionInternal { // V1.1.3300
private static int _objectTypeCount;
internal readonly int _objectID = Interlocked.Increment(ref _objectTypeCount);
internal static readonly StateChangeEventArgs StateChangeClosed = new StateChangeEventArgs(ConnectionState.Open, ConnectionState.Closed);
internal static readonly StateChangeEventArgs StateChangeOpen = new StateChangeEventArgs(ConnectionState.Closed, ConnectionState.Open);
private readonly bool _allowSetConnectionString;
private readonly bool _hidePassword;
private readonly ConnectionState _state;
private readonly WeakReference _owningObject = new WeakReference(null, false); // [usage must be thread safe] the owning object, when not in the pool. (both Pooled and Non-Pooled connections)
// should only be used by DbConnectionPool.DbConnectionInternalListStack.Synchronized(Push|Pop)
private DbConnectionInternal _nextPooledObject;
internal DbConnectionInternal NextPooledObject {
get { return _nextPooledObject; }
set { _nextPooledObject = value; }
}
private DbConnectionPool _connectionPool; // the pooler that the connection came from (Pooled connections only)
private DbConnectionPoolCounters _performanceCounters; // the performance counters we're supposed to update
private DbReferenceCollection _referenceCollection; // collection of objects that we need to notify in some way when we're being deactivated
private int _pooledCount; // [usage must be thread safe] the number of times this object has been pushed into the pool less the number of times it's been popped (0 != inPool)
private bool _connectionIsDoomed; // true when the connection should no longer be used.
private bool _cannotBePooled; // true when the connection should no longer be pooled.
private bool _isInStasis;
private DateTime _createTime; // when the connection was created.
private SysTx.Transaction _enlistedTransaction; // [usage must be thread-safe] the transaction that we're enlisted in, either manually or automatically
#if DEBUG
private int _activateCount; // debug only counter to verify activate/deactivates are in [....].
#endif //DEBUG
protected DbConnectionInternal() : this(ConnectionState.Open, true, false) { // V1.1.3300
}
// Constructor for internal connections
internal DbConnectionInternal(ConnectionState state, bool hidePassword, bool allowSetConnectionString) {
_allowSetConnectionString = allowSetConnectionString;
_hidePassword = hidePassword;
_state = state;
}
internal bool AllowSetConnectionString {
get {
return _allowSetConnectionString;
}
}
internal bool CanBePooled {
get {
bool flag = (!_connectionIsDoomed && !_cannotBePooled && !_owningObject.IsAlive);
return flag;
}
}
protected internal SysTx.Transaction EnlistedTransaction {
get {
return _enlistedTransaction;
}
set {
if (((null == _enlistedTransaction) && (null != value))
|| ((null != _enlistedTransaction) && !_enlistedTransaction.Equals(value))) { // WebData 20000024
// Pay attention to the order here:
// 1) defect from any notifications
// 2) replace the transaction
// 3) re-enlist in notifications for the new transaction
// SQLBUDT #230558 we need to use a clone of the transaction
// when we store it, or we'll end up keeping it past the
// duration of the using block of the TransactionScope
SysTx.Transaction valueClone = null;
SysTx.Transaction previousTransactionClone = null;
try {
if (null != value) {
valueClone = value.Clone();
}
// NOTE: rather than take locks around several potential round-
// trips to the server, and/or virtual function calls, we simply
// presume that you aren't doing something illegal from multiple
// threads, and check once we get around to finalizing things
// inside a lock.
lock(this) {
// NOTE: There is still a race condition here, when we are
// called from EnlistTransaction (which cannot re-enlist)
// instead of EnlistDistributedTransaction (which can),
// however this should have been handled by the outer
// connection which checks to ensure that it's OK. The
// only case where we have the race condition is multiple
// concurrent enlist requests to the same connection, which
// is a bit out of line with something we should have to
// support.
previousTransactionClone = _enlistedTransaction;
_enlistedTransaction = valueClone;
value = valueClone;
valueClone = null; // we've stored it, don't dispose it.
}
}
finally {
// we really need to dispose our clones; they may have
// native resources and GC may not happen soon enough.
if (null != previousTransactionClone) {
previousTransactionClone.Dispose();
}
if (null != valueClone) {
valueClone.Dispose();
}
}
// I don't believe that we need to lock to protect the actual
// enlistment in the transaction; it would only protect us
// against multiple concurrent calls to enlist, which really
// isn't supported anyway.
if (null != value) {
if (Bid.IsOn(DbConnectionPool.PoolerTracePoints)) {
int x = value.GetHashCode();
Bid.PoolerTrace(" %d#, Transaction %d#, Enlisting.\n", ObjectID, x);
}
TransactionOutcomeEnlist(value);
}
}
}
}
// Is this connection in stasis, waiting for transaction to end before returning to pool?
internal bool IsTxRootWaitingForTxEnd {
get {
return _isInStasis;
}
}
virtual internal bool RequireExplicitTransactionUnbind {
get {
return false; // override to add explicit unbind requirement
}
}
// Is this a connection that must be put in stasis (or is already in stasis) pending the end of it's transaction?
virtual protected internal bool IsNonPoolableTransactionRoot {
get {
return false; // if you want to have delegated transactions that are non-poolable, you better override this...
}
}
virtual internal bool IsTransactionRoot {
get {
return false; // if you want to have delegated transactions, you better override this...
}
}
public bool HasEnlistedTransaction {
get {
return (null != EnlistedTransaction); // NOTE: race condition in EnlistedTransaction applies here too.
}
}
protected internal bool IsConnectionDoomed {
get {
return _connectionIsDoomed;
}
}
internal bool IsEmancipated {
get {
// NOTE: There are race conditions between PrePush, PostPop and this
// property getter -- only use this while this object is locked;
// (DbConnectionPool.Clear and ReclaimEmancipatedObjects
// do this for us)
// Remember how this works (I keep getting confused...)
//
// _pooledCount is incremented when the connection is pushed into the pool
// _pooledCount is decremented when the connection is popped from the pool
// _pooledCount is set to -1 when the connection is not pooled (just in case...)
//
// That means that:
//
// _pooledCount > 1 connection is in the pool multiple times (this is a serious bug...)
// _pooledCount == 1 connection is in the pool
// _pooledCount == 0 connection is out of the pool
// _pooledCount == -1 connection is not a pooled connection; we shouldn't be here for non-pooled connections.
// _pooledCount < -1 connection out of the pool multiple times (not sure how this could happen...)
//
// Now, our job is to return TRUE when the connection is out
// of the pool and it's owning object is no longer around to
// return it.
bool value = !IsTxRootWaitingForTxEnd && (_pooledCount < 1) && !_owningObject.IsAlive;
return value;
}
}
internal int ObjectID {
get {
return _objectID;
}
}
protected internal object Owner {
// We use a weak reference to the owning object so we can identify when
// it has been garbage collected without thowing exceptions.
get {
return _owningObject.Target;
}
}
internal DbConnectionPool Pool {
get {
return _connectionPool;
}
}
protected DbConnectionPoolCounters PerformanceCounters {
get {
return _performanceCounters;
}
}
virtual protected bool ReadyToPrepareTransaction {
get {
return true;
}
}
protected internal DbReferenceCollection ReferenceCollection {
get {
return _referenceCollection;
}
}
abstract public string ServerVersion {
get;
}
// this should be abstract but untill it is added to all the providers virtual will have to do [....]
virtual public string ServerVersionNormalized {
get{
throw ADP.NotSupported();
}
}
public bool ShouldHidePassword {
get {
return _hidePassword;
}
}
public ConnectionState State {
get {
return _state;
}
}
abstract protected void Activate(SysTx.Transaction transaction);
internal void ActivateConnection(SysTx.Transaction transaction) {
// Internal method called from the connection pooler so we don't expose
// the Activate method publicly.
Bid.PoolerTrace(" %d#, Activating\n", ObjectID);
#if DEBUG
int activateCount = Interlocked.Increment(ref _activateCount);
Debug.Assert(1 == activateCount, "activated multiple times?");
#endif // DEBUG
Activate(transaction);
PerformanceCounters.NumberOfActiveConnections.Increment();
}
internal void AddWeakReference(object value, int tag) {
if (null == _referenceCollection) {
_referenceCollection = CreateReferenceCollection();
if (null == _referenceCollection) {
throw ADP.InternalError(ADP.InternalErrorCode.CreateReferenceCollectionReturnedNull);
}
}
_referenceCollection.Add(value, tag);
}
abstract public DbTransaction BeginTransaction(IsolationLevel il);
virtual public void ChangeDatabase(string value) {
throw ADP.MethodNotImplemented("ChangeDatabase");
}
internal virtual void CloseConnection(DbConnection owningObject, DbConnectionFactory connectionFactory) {
// The implementation here is the implementation required for the
// "open" internal connections, since our own private "closed"
// singleton internal connection objects override this method to
// prevent anything funny from happening (like disposing themselves
// or putting them into a connection pool)
//
// Derived class should override DbConnectionInternal.Deactivate and DbConnectionInternal.Dispose
// for cleaning up after DbConnection.Close
// protected override void Deactivate() { // override DbConnectionInternal.Close
// // do derived class connection deactivation for both pooled & non-pooled connections
// }
// public override void Dispose() { // override DbConnectionInternal.Close
// // do derived class cleanup
// base.Dispose();
// }
//
// overriding DbConnection.Close is also possible, but must provider for their own synchronization
// public override void Close() { // override DbConnection.Close
// base.Close();
// // do derived class outer connection for both pooled & non-pooled connections
// // user must do their own synchronization here
// }
//
// if the DbConnectionInternal derived class needs to close the connection it should
// delegate to the DbConnection if one exists or directly call dispose
// DbConnection owningObject = (DbConnection)Owner;
// if (null != owningObject) {
// owningObject.Close(); // force the closed state on the outer object.
// }
// else {
// Dispose();
// }
//
////////////////////////////////////////////////////////////////
// DON'T MESS WITH THIS CODE UNLESS YOU KNOW WHAT YOU'RE DOING!
////////////////////////////////////////////////////////////////
Debug.Assert(null != owningObject, "null owningObject");
Debug.Assert(null != connectionFactory, "null connectionFactory");
Debug.Assert(owningObject == Owner, "Close with different owner");
Debug.Assert(connectionFactory.GetInnerConnection(owningObject) == this || this.IsConnectionDoomed, "Close of not this");
Bid.PoolerTrace(" %d# Closing.\n", ObjectID);
// if an exception occurs after the state change but before the try block
// the connection will be stuck in OpenBusy state. The commented out try-catch
// block doesn't really help because a ThreadAbort during the finally block
// would just refert the connection to a bad state.
// Open->Closed: guarantee internal connection is returned to correct pool
if (connectionFactory.SetInnerConnectionFrom(owningObject, DbConnectionOpenBusy.SingletonInstance, this)) {
try {
DbConnectionPool connectionPool = Pool;
// Detach from enlisted transactions that are no longer active on close
SysTx.Transaction enlistedTransaction = EnlistedTransaction;
if (null != enlistedTransaction && SysTx.TransactionStatus.Active != enlistedTransaction.TransactionInformation.Status) {
DetachTransaction(enlistedTransaction);
}
// The singleton closed classes won't have owners and
// connection pools, and we won't want to put them back
// into the pool.
if (null != connectionPool) {
connectionPool.PutObject(this, owningObject); // PutObject calls Deactivate for us...
// NOTE: Before we leave the PutObject call, another
// thread may have already popped the connection from
// the pool, so don't expect to be able to verify it.
}
else {
Deactivate(); // ensure we de-activate non-pooled connections, or the data readers and transactions may not get cleaned up...
PerformanceCounters.HardDisconnectsPerSecond.Increment();
// To prevent an endless recursion, we need to clear
// the owning object before we call dispose so that
// we can't get here a second time... Ordinarily, I
// would call setting the owner to null a hack, but
// this is safe since we're about to dispose the
// object and it won't have an owner after that for
// certain.
_owningObject.Target = null;
if (IsTransactionRoot) {
SetInStasis();
}
else {
PerformanceCounters.NumberOfNonPooledConnections.Decrement();
#if !ORACLE
if (this.GetType() != typeof(System.Data.SqlClient.SqlInternalConnectionSmi))
#endif
{
Dispose();
}
}
}
}
finally {
// if a ThreadAbort puts us here then its possible the outer connection will not reference
// this and this will be orphaned, not reclaimed by object pool until outer connection goes out of scope.
connectionFactory.SetInnerConnectionEvent(owningObject, DbConnectionClosedPreviouslyOpened.SingletonInstance);
}
}
}
virtual protected DbReferenceCollection CreateReferenceCollection() {
throw ADP.InternalError(ADP.InternalErrorCode.AttemptingToConstructReferenceCollectionOnStaticObject);
}
abstract protected void Deactivate();
internal void DeactivateConnection() {
// Internal method called from the connection pooler so we don't expose
// the Deactivate method publicly.
Bid.PoolerTrace(" %d#, Deactivating\n", ObjectID);
#if DEBUG
int activateCount = Interlocked.Decrement(ref _activateCount);
Debug.Assert(0 == activateCount, "activated multiple times?");
#endif // DEBUG
PerformanceCounters.NumberOfActiveConnections.Decrement();
if (!_connectionIsDoomed && Pool.UseLoadBalancing) {
// If we're not already doomed, check the connection's lifetime and
// doom it if it's lifetime has elapsed.
DateTime now = DateTime.UtcNow; // WebData 111116
if ((now.Ticks - _createTime.Ticks) > Pool.LoadBalanceTimeout.Ticks) {
DoNotPoolThisConnection();
}
}
Deactivate();
}
virtual internal void DelegatedTransactionEnded() {
// Called by System.Transactions when the delegated transaction has
// completed. We need to make closed connections that are in stasis
// available again, or disposed closed/leaked non-pooled connections.
// IMPORTANT NOTE: You must have taken a lock on the object before
// you call this method to prevent race conditions with Clear and
// ReclaimEmancipatedObjects.
Bid.Trace(" %d#, Delegated Transaction Completed.\n", ObjectID);
if (1 == _pooledCount) {
// When _pooledCount is 1, it indicates a closed, pooled,
// connection so it is ready to put back into the pool for
// general use.
TerminateStasis(true);
Deactivate(); // call it one more time just in case
DbConnectionPool pool = Pool;
if (null == pool) {
throw ADP.InternalError(ADP.InternalErrorCode.PooledObjectWithoutPool); // pooled connection does not have a pool
}
pool.PutObjectFromTransactedPool(this);
}
else if (-1 == _pooledCount && !_owningObject.IsAlive) {
// When _pooledCount is -1 and the owning object no longer exists,
// it indicates a closed (or leaked), non-pooled connection so
// it is safe to dispose.
TerminateStasis(false);
Deactivate(); // call it one more time just in case
// it's a non-pooled connection, we need to dispose of it
// once and for all, or the server will have fits about us
// leaving connections open until the client-side GC kicks
// in.
PerformanceCounters.NumberOfNonPooledConnections.Decrement();
Dispose();
}
// When _pooledCount is 0, the connection is a pooled connection
// that is either open (if the owning object is alive) or leaked (if
// the owning object is not alive) In either case, we can't muck
// with the connection here.
}
public virtual void Dispose() {
_connectionPool = null;
_performanceCounters = null;
_connectionIsDoomed = true;
_enlistedTransaction = null; //
}
protected internal void DoNotPoolThisConnection() {
_cannotBePooled = true;
Bid.PoolerTrace(" %d#, Marking pooled object as non-poolable so it will be disposed\n", ObjectID);
}
/// Ensure that this connection cannot be put back into the pool.
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
protected internal void DoomThisConnection() {
_connectionIsDoomed = true;
Bid.PoolerTrace(" %d#, Dooming\n", ObjectID);
}
abstract public void EnlistTransaction(SysTx.Transaction transaction);
virtual protected internal DataTable GetSchema(DbConnectionFactory factory, DbConnectionPoolGroup poolGroup, DbConnection outerConnection, string collectionName, string[] restrictions){
Debug.Assert(outerConnection != null,"outerConnection may not be null.");
DbMetaDataFactory metaDataFactory = factory.GetMetaDataFactory(poolGroup, this);
Debug.Assert(metaDataFactory != null,"metaDataFactory may not be null.");
return metaDataFactory.GetSchema(outerConnection, collectionName,restrictions);
}
internal void MakeNonPooledObject(object owningObject, DbConnectionPoolCounters performanceCounters) {
// Used by DbConnectionFactory to indicate that this object IS NOT part of
// a connection pool.
_connectionPool = null;
_performanceCounters = performanceCounters;
_owningObject.Target = owningObject;
_pooledCount = -1;
}
internal void MakePooledConnection(DbConnectionPool connectionPool) {
// Used by DbConnectionFactory to indicate that this object IS part of
// a connection pool.
//
_createTime = DateTime.UtcNow; // WebData 111116
_connectionPool = connectionPool;
_performanceCounters = connectionPool.PerformanceCounters;
}
internal void NotifyWeakReference(int message) {
DbReferenceCollection referenceCollection = ReferenceCollection;
if (null != referenceCollection) {
referenceCollection.Notify(message);
}
}
/// The default implementation is for the open connection objects, and
/// it simply throws. Our private closed-state connection objects
/// override this and do the correct thing.
// User code should either override DbConnectionInternal.Activate when it comes out of the pool
// or override DbConnectionFactory.CreateConnection when the connection is created for non-pooled connections
internal virtual void OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory) {
throw ADP.ConnectionAlreadyOpen(State);
}
internal void PrePush(object expectedOwner) {
// Called by DbConnectionPool when we're about to be put into it's pool, we
// take this opportunity to ensure ownership and pool counts are legit.
// IMPORTANT NOTE: You must have taken a lock on the object before
// you call this method to prevent race conditions with Clear and
// ReclaimEmancipatedObjects.
//3 // The following tests are retail assertions of things we can't allow to happen.
if (null == expectedOwner) {
if (null != _owningObject.Target) {
throw ADP.InternalError(ADP.InternalErrorCode.UnpooledObjectHasOwner); // new unpooled object has an owner
}
}
else if (_owningObject.Target != expectedOwner) {
throw ADP.InternalError(ADP.InternalErrorCode.UnpooledObjectHasWrongOwner); // unpooled object has incorrect owner
}
if (0 != _pooledCount) {
throw ADP.InternalError(ADP.InternalErrorCode.PushingObjectSecondTime); // pushing object onto stack a second time
}
if (Bid.IsOn(DbConnectionPool.PoolerTracePoints)) {
//DbConnection x = (expectedOwner as DbConnection);
Bid.PoolerTrace(" %d#, Preparing to push into pool, owning connection %d#, pooledCount=%d\n", ObjectID, 0, _pooledCount);
}
_pooledCount++;
_owningObject.Target = null; // NOTE: doing this and checking for InternalError.PooledObjectHasOwner degrades the close by 2%
}
internal void PostPop(object newOwner) {
// Called by DbConnectionPool right after it pulls this from it's pool, we
// take this opportunity to ensure ownership and pool counts are legit.
Debug.Assert(!IsEmancipated,"pooled object not in pool");
// SQLBUDT #356871 -- When another thread is clearing this pool, it
// will doom all connections in this pool without prejudice which
// causes the following assert to fire, which really mucks up stress
// against checked bits. The assert is benign, so we're commenting
// it out.
//Debug.Assert(CanBePooled, "pooled object is not poolable");
// IMPORTANT NOTE: You must have taken a lock on the object before
// you call this method to prevent race conditions with Clear and
// ReclaimEmancipatedObjects.
if (null != _owningObject.Target) {
throw ADP.InternalError(ADP.InternalErrorCode.PooledObjectHasOwner); // pooled connection already has an owner!
}
_owningObject.Target = newOwner;
_pooledCount--;
if (Bid.IsOn(DbConnectionPool.PoolerTracePoints)) {
//DbConnection x = (newOwner as DbConnection);
Bid.PoolerTrace(" %d#, Preparing to pop from pool, owning connection %d#, pooledCount=%d\n", ObjectID, 0, _pooledCount);
}
//3 // The following tests are retail assertions of things we can't allow to happen.
if (null != Pool) {
if (0 != _pooledCount) {
throw ADP.InternalError(ADP.InternalErrorCode.PooledObjectInPoolMoreThanOnce); // popping object off stack with multiple pooledCount
}
}
else if (-1 != _pooledCount) {
throw ADP.InternalError(ADP.InternalErrorCode.NonPooledObjectUsedMoreThanOnce); // popping object off stack with multiple pooledCount
}
}
internal void RemoveWeakReference(object value) {
DbReferenceCollection referenceCollection = ReferenceCollection;
if (null != referenceCollection) {
referenceCollection.Remove(value);
}
}
// Cleanup connection's transaction-specific structures (currently used by Delegated transaction).
// This is a separate method because cleanup can be triggered in multiple ways for a delegated
// transaction.
virtual protected void CleanupTransactionOnCompletion(SysTx.Transaction transaction) {
}
// Detach transaction from connection.
internal void DetachTransaction(SysTx.Transaction transaction) {
Bid.Trace(" %d#, Transaction Completed. (pooledCount=%d)\n", ObjectID, _pooledCount);
// potentially a multi-threaded event, so lock the connection to make sure we don't enlist in a new
// transaction between compare and assignment. No need to short circuit outside of lock, since failed comparisons should
// be the exception, not the rule.
lock (this) {
// Detach if detach-on-end behavior, or if outer connection was closed
DbConnection owner = (DbConnection)Owner;
if (!RequireExplicitTransactionUnbind || null == owner) {
if (_enlistedTransaction != null && transaction.Equals(_enlistedTransaction)) {
EnlistedTransaction = null;
if (IsTxRootWaitingForTxEnd) {
DelegatedTransactionEnded();
}
}
}
}
}
// Handle transaction detach, pool cleanup and other post-transaction cleanup tasks associated with
internal void CleanupConnectionOnTransactionCompletion(SysTx.Transaction transaction) {
DetachTransaction(transaction);
DbConnectionPool pool = Pool;
if (null != pool) {
pool.TransactionEnded(transaction, this);
}
}
void TransactionCompletedEvent(object sender, SysTx.TransactionEventArgs e) {
SysTx.Transaction transaction = e.Transaction;
Bid.Trace(" %d#, Transaction Completed. (pooledCount=%d)\n", ObjectID, _pooledCount);
CleanupTransactionOnCompletion(transaction);
CleanupConnectionOnTransactionCompletion(transaction);
}
//
[SecurityPermission(SecurityAction.Assert, Flags=SecurityPermissionFlag.UnmanagedCode)]
private void TransactionOutcomeEnlist(SysTx.Transaction transaction) {
transaction.TransactionCompleted += new SysTx.TransactionCompletedEventHandler(TransactionCompletedEvent);
}
internal void SetInStasis() {
_isInStasis = true;
Bid.PoolerTrace(" %d#, Non-Pooled Connection has Delegated Transaction, waiting to Dispose.\n", ObjectID);
PerformanceCounters.NumberOfStasisConnections.Increment();
}
private void TerminateStasis(bool returningToPool) {
if (returningToPool) {
Bid.PoolerTrace(" %d#, Delegated Transaction has ended, connection is closed. Returning to general pool.\n", ObjectID);
}
else {
Bid.PoolerTrace(" %d#, Delegated Transaction has ended, connection is closed/leaked. Disposing.\n", ObjectID);
}
PerformanceCounters.NumberOfStasisConnections.Decrement();
_isInStasis = 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
- DataControlCommands.cs
- SyntaxCheck.cs
- Utils.cs
- Models.cs
- PriorityBinding.cs
- NavigatorInput.cs
- UpdatePanelTrigger.cs
- StyleCollection.cs
- ZipIOModeEnforcingStream.cs
- ConstructorArgumentAttribute.cs
- X509ServiceCertificateAuthenticationElement.cs
- EventlogProvider.cs
- WebPartZoneBase.cs
- WebPermission.cs
- X509Certificate2Collection.cs
- Decoder.cs
- ResXDataNode.cs
- WindowsGraphics.cs
- RepeaterItem.cs
- WindowsScroll.cs
- MemoryPressure.cs
- EnumerableRowCollectionExtensions.cs
- COAUTHINFO.cs
- CryptoKeySecurity.cs
- DbConnectionPoolIdentity.cs
- IncrementalHitTester.cs
- XamlReaderHelper.cs
- ListChunk.cs
- TransformCollection.cs
- OutputCacheProfileCollection.cs
- XamlFxTrace.cs
- SafeNativeMethodsMilCoreApi.cs
- XmlBindingWorker.cs
- ObjectResult.cs
- MULTI_QI.cs
- CommandBinding.cs
- _UriTypeConverter.cs
- CodeActivityContext.cs
- CacheChildrenQuery.cs
- PeerTransportListenAddressConverter.cs
- DBConnectionString.cs
- ParserContext.cs
- BaseTemplateCodeDomTreeGenerator.cs
- DbInsertCommandTree.cs
- ToolBarPanel.cs
- GridViewRowPresenterBase.cs
- TypeUnloadedException.cs
- FixedNode.cs
- FontUnitConverter.cs
- PointConverter.cs
- StylusPointPropertyInfoDefaults.cs
- WorkflowLayouts.cs
- SqlClientPermission.cs
- Typeface.cs
- TriggerAction.cs
- DoubleCollectionConverter.cs
- BamlBinaryWriter.cs
- ContainerActivationHelper.cs
- LinearKeyFrames.cs
- graph.cs
- DataGridViewColumnTypeEditor.cs
- __Error.cs
- SqlInternalConnectionSmi.cs
- PrePrepareMethodAttribute.cs
- Control.cs
- IndexingContentUnit.cs
- DrawingDrawingContext.cs
- TempFiles.cs
- XmlNotation.cs
- PackagePartCollection.cs
- QuadraticEase.cs
- EntityDataSourceSelectingEventArgs.cs
- HexParser.cs
- InvokeGenerator.cs
- ToolStripTextBox.cs
- ActivationWorker.cs
- AccessViolationException.cs
- PersonalizationProvider.cs
- ContainerVisual.cs
- ConnectionStringEditor.cs
- HtmlShimManager.cs
- RewritingPass.cs
- SqlCachedBuffer.cs
- JsonServiceDocumentSerializer.cs
- _IPv6Address.cs
- MouseGestureValueSerializer.cs
- ClientConfigPaths.cs
- XmlUtil.cs
- ListView.cs
- FunctionImportElement.cs
- DispatcherProcessingDisabled.cs
- PanelDesigner.cs
- ThreadInterruptedException.cs
- Int16.cs
- SequentialWorkflowRootDesigner.cs
- ZipIOEndOfCentralDirectoryBlock.cs
- XNodeValidator.cs
- ProviderMetadataCachedInformation.cs
- PriorityQueue.cs
- WebBrowserProgressChangedEventHandler.cs