System.Net.ConnectionPool.Get C# (CSharp) Method

Get() private method

Retrieves the pooled stream out of the pool, does this by using the result of a WaitAny as input, and then based on whether it has a mutex, event, semaphore, or timeout decides what action to take

private Get ( object owningObject, int result, bool &continueLoop, WaitHandle &waitHandles ) : PooledStream
owningObject object
result int
continueLoop bool
waitHandles System.Threading.WaitHandle
return PooledStream
        private PooledStream Get(object owningObject, int result, ref bool continueLoop, ref WaitHandle [] waitHandles) {
                PooledStream pooledStream = null;
                GlobalLog.Enter("ConnectionPool#" + ValidationHelper.HashString(this) + "::Get", result.ToString());


                // From the WaitAny docs: "If more than one object became signaled during
                // the call, this is the array index of the signaled object with the
                // smallest index value of all the signaled objects."  This is important
                // so that the free object signal will be returned before a creation
                // signal.

                switch (result) {
                case WaitTimeout:
                    Interlocked.Decrement(ref m_WaitCount);
                    continueLoop = false;
                    GlobalLog.Leave("ConnectionPool#" + ValidationHelper.HashString(this) + "::Get","throw Timeout WebException");
                    throw new WebException(NetRes.GetWebStatusString("net_timeout", WebExceptionStatus.ConnectFailure), WebExceptionStatus.Timeout);


                case ErrorHandleIndex:
                    // Throw the error that PoolCreateRequest stashed.
                    int newWaitCount = Interlocked.Decrement(ref m_WaitCount);
                    continueLoop = false;
                    Exception exceptionToThrow = m_ResError;
                    if (newWaitCount == 0) {
                        CancelErrorCallback();
                    }
                    throw exceptionToThrow;

                case CreationHandleIndex:
                    try {
                        continueLoop = true;
                        pooledStream = UserCreateRequest();

                        if (null != pooledStream) {
                            pooledStream.PostPop(owningObject);
                            Interlocked.Decrement(ref m_WaitCount);
                            continueLoop = false;

                        }
                        else {
                            // If we were not able to create an object, check to see if
                            // we reached MaxPoolSize.  If so, we will no longer wait on
                            // the CreationHandle, but instead wait for a free object or
                            // the timeout.

                            // BUG - if we receive the CreationHandle midway into the wait
                            // period and re-wait, we will be waiting on the full period
                            if (Count >= MaxPoolSize && 0 != MaxPoolSize) {
                                if (!ReclaimEmancipatedObjects()) {
                                    // modify handle array not to wait on creation mutex anymore
                                    waitHandles    = new WaitHandle[2];
                                    waitHandles[0] = m_WaitHandles[0];
                                    waitHandles[1] = m_WaitHandles[1];
                                }
                            }

                        }
                    }
                    finally {
                        CreationMutex.ReleaseMutex();
                    }
                    break;

                default:
                    //
                    //    guaranteed available inventory
                    //
                    Interlocked.Decrement(ref m_WaitCount);
                    pooledStream = GetFromPool(owningObject);
                    continueLoop = false;
                    break;
                }
                GlobalLog.Leave("ConnectionPool#" + ValidationHelper.HashString(this) + "::Get",ValidationHelper.HashString(pooledStream));
                return pooledStream;
        }