示例#1
0
        public bool PostRequest(WorkRequestDelegate cb, object state, out IWorkRequest reqStatus)
        {
            WorkRequest request = new WorkRequest(cb, state, _propogateThreadPrincipal, _propogateCallContext);

            reqStatus = request;
            return(PostRequest(request));
        }
示例#2
0
            public int State = PENDING;           // The state of this particular request.

            public WorkRequest(WorkRequestDelegate cb, object arg,
                               bool propogateThreadPrincipal, bool propogateCallContext)
            {
                TargetProc = cb;
                ProcArg    = arg;
                ProcArgs   = null;

                Initialize(propogateThreadPrincipal, propogateCallContext);
            }
示例#3
0
            internal int state = PENDING;          // The state of this particular request.
            #endregion

            #region constructor

            /// <summary> Initializes a new instance of the <see cref="WorkRequest"/> class. </summary>
            /// <param name="cb"> Documentation in progress... </param>
            /// <param name="arg"> Documentation in progress... </param>
            /// <param name="propagateThreadPrincipal"> Documentation in progress... </param>
            /// <param name="propagateCallContext"> Documentation in progress... </param>
            /// <param name="propagateCASMarkers"> Documentation in progress... </param>
            public WorkRequest(WorkRequestDelegate cb, object arg,
                               bool propagateThreadPrincipal, bool propagateCallContext, bool propagateCASMarkers)
            {
                targetProc = cb;
                procArg    = arg;
                procArgs   = null;

                Initialize(propagateThreadPrincipal, propagateCallContext, propagateCASMarkers);
            }
示例#4
0
            internal DateTime workingTime; // Current timestamp used for triggering new threads (moving target).

            #endregion Fields

            #region Constructors

            public WorkRequest( WorkRequestDelegate cb, object arg,
                                bool propogateThreadPrincipal, bool propogateCallContext,
                                bool propogateHttpContext, bool propogateCASMarkers )
            {
                targetProc = cb;
                procArg = arg;
                procArgs = null;

                Initialize( propogateThreadPrincipal, propogateCallContext,
                            propogateHttpContext, propogateCASMarkers );
            }
示例#5
0
 public bool PostRequest( WorkRequestDelegate cb, object state, out IWorkRequest reqStatus )
 {
     WorkRequest request =
         new WorkRequest( cb, state,
                          propogateThreadPrincipal, propogateCallContext,
                          propogateHttpContext, propogateCASMarkers );
     reqStatus = request;
     return PostRequest(request);
 }
示例#6
0
 public bool PostRequest( WorkRequestDelegate cb, object state )
 {
     IWorkRequest notUsed;
     return PostRequest(cb, state, out notUsed);
 }
示例#7
0
 // Overloads for the early bound WorkRequestDelegate-based targets.
 //
 public bool PostRequest( WorkRequestDelegate cb )
 {
     return PostRequest(cb, (object)null);
 }
示例#8
0
            void ThreadProc()
            {
                Debug.WriteLine(string.Format("[{0}, {1}] Worker thread started",
                                              Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.Name));

                bool done = false;

                while (!done)
                {
                    WorkRequest   wr        = null;
                    ThreadWrapper newThread = null;

                    lock (this.poolLock)
                    {
                        // As long as the request queue is empty and a shutdown hasn't
                        // been initiated, wait for a new work request to arrive.
                        //
                        bool timedOut = false;

                        while (!pool.stopInProgress && !timedOut && (pool.requestQueue.Count == 0))
                        {
                            if (!Monitor.Wait(pool, (isPermanent ? Timeout.Infinite : pool.decayTime)))
                            {
                                // Timed out waiting for something to do.  Only dynamically created
                                // threads will get here, so bail out.
                                //
                                timedOut = true;
                            }
                        }

                        // We exited the loop above because one of the following conditions
                        // was met:
                        //   - ThreadPool.Stop was called to initiate a shutdown.
                        //   - A dynamic thread timed out waiting for a work request to arrive.
                        //   - There are items in the work queue to process.

                        // If we exited the loop because there's work to be done,
                        // a shutdown hasn't been initiated, and we aren't a dynamic thread
                        // that timed out, pull the request off the queue and prepare to
                        // process it.
                        //
                        if (!pool.stopInProgress && !timedOut && (pool.requestQueue.Count > 0))
                        {
                            wr = (WorkRequest)pool.requestQueue.Dequeue();
                            Debug.Assert(wr != null);

                            // Check to see if this work request languished in the queue
                            // very long.  If it was in the queue >= the new thread trigger
                            // time, and if we haven't reached the max thread count cap,
                            // add a new thread to the pool.
                            //
                            // If the decision is made, create the new thread object (updating
                            // the current # of threads in the pool), but defer starting the new
                            // thread until the lock is released.
                            //
                            TimeSpan requestTimeInQ = DateTime.Now.Subtract(wr.workingTime);

                            if ((requestTimeInQ >= pool.newThreadTrigger) && (pool.currentThreadCount < pool.maxThreadCount))
                            {
                                // Note - the constructor for ThreadWrapper will update
                                // pool.currentThreadCount.
                                //
                                newThread =
                                    new ThreadWrapper(pool, false, priority,
                                                      string.Format("{0} (dynamic)", pool.threadPoolName));

                                // Since the current request we just dequeued is stale,
                                // everything else behind it in the queue is also stale.
                                // So reset the timestamps of the remaining pending work
                                // requests so that we don't start creating threads
                                // for every subsequent request.
                                //
                                pool.ResetWorkRequestTimes();
                            }
                        }
                        else
                        {
                            // Should only get here if this is a dynamic thread that
                            // timed out waiting for a work request, or if the pool
                            // is shutting down.
                            //
                            Debug.Assert((timedOut && !isPermanent) || pool.stopInProgress);
                            pool.currentThreadCount--;

                            if (pool.currentThreadCount == 0)
                            {
                                // Last one out turns off the lights.
                                //
                                Debug.Assert(pool.stopInProgress);

                                if (pool.Stopped != null)
                                {
                                    pool.Stopped();
                                }

                                pool.stopCompleteEvent.Set();
                            }

                            done = true;
                        }
                    } // lock

                    // No longer holding pool lock here...

                    if (!done && (wr != null))
                    {
                        // Check to see if this request has been cancelled while
                        // stuck in the work queue.
                        //
                        // If the work request was pending, mark it processed and proceed
                        // to handle.  Otherwise, the request must have been cancelled
                        // before we plucked it off the request queue.
                        //
                        if (Interlocked.CompareExchange(ref wr.state, WorkRequest.PROCESSED, WorkRequest.PENDING) != WorkRequest.PENDING)
                        {
                            // Request was cancelled before we could get here.
                            // Bail out.
                            continue;
                        }

                        if (newThread != null)
                        {
                            Debug.WriteLine(string.Format("[{0}, {1}] Adding dynamic thread to pool",
                                                          Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.Name));
                            newThread.Start();
                        }

                        // Dispatch the work request.
                        //
                        ThreadInfo originalThreadInfo = null;

                        try
                        {
                            // Impersonate (as much as possible) what we know about
                            // the thread that issued the work request.
                            //
                            originalThreadInfo = ThreadInfo.Impersonate(wr.threadInfo);

                            WorkRequestDelegate targetProc = wr.targetProc as WorkRequestDelegate;

                            if (targetProc != null)
                            {
                                targetProc(wr.procArg, wr.timeStampStarted);
                            }
                            else
                            {
                                wr.targetProc.DynamicInvoke(wr.procArgs);
                            }
                        }
                        catch (Exception e)
                        {
                            Debug.WriteLine(string.Format("Exception thrown performing callback:\n{0}\n{1}", e.Message, e.StackTrace));
                        }
                        finally
                        {
                            // Restore our worker thread's identity.
                            //
                            ThreadInfo.Restore(originalThreadInfo);
                        }
                    }
                }

                Debug.WriteLine(string.Format("[{0}, {1}] Worker thread exiting pool",
                                              Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.Name));
            }
示例#9
0
        public bool PostRequest(WorkRequestDelegate cb, object state)
        {
            IWorkRequest notUsed;

            return(PostRequest(cb, state, out notUsed));
        }
示例#10
0
 // Overloads for the early bound WorkRequestDelegate-based targets.
 //
 public bool PostRequest(WorkRequestDelegate cb)
 {
     return(PostRequest(cb, (object)null));
 }
示例#11
0
            private void ThreadProc()
            {
                bool done = false;

                while (!done)
                {
                    WorkRequest   wr        = null;
                    ThreadWrapper newThread = null;

                    Monitor.Enter(_pool._syncLock);
                    try
                    {
                        /*
                         * As long as the request queue is empty and a shutdown hasn't
                         * been initiated, wait for a new work request to arrive.
                         */
                        bool timedOut = false;

                        while (!_pool._stopInProgress && !timedOut && _pool._requestQueue.Count == 0)
                        {
                            if (!Monitor.Wait(_pool._syncLock, _permanent ? Timeout.Infinite : _pool._decayTime))
                            {
                                /*
                                 * Timed out waiting for something to do.  Only dynamically created
                                 * threads will get here, so bail out.
                                 */
                                timedOut = true;
                            }
                        }

                        /*
                         * We exited the loop above because one of the following conditions
                         * was met:
                         *   - ThreadPool.Stop was called to initiate a shutdown.
                         *   - A dynamic thread timed out waiting for a work request to arrive.
                         *   - There are items in the work queue to process.
                         *
                         * If we exited the loop because there's work to be done,
                         * a shutdown hasn't been initiated, and we aren't a dynamic thread
                         * that timed out, pull the request off the queue and prepare to
                         * process it.
                         */
                        if (!_pool._stopInProgress && !timedOut && _pool._requestQueue.Count > 0)
                        {
                            wr = _pool._requestQueue.Dequeue();

                            /*
                             * Check to see if this work request languished in the queue
                             * very long.  If it was in the queue >= the new thread trigger
                             * time, and if we haven't reached the max thread count cap,
                             * add a new thread to the pool.
                             *
                             * If the decision is made, create the new thread object (updating
                             * the current # of threads in the pool), but defer starting the new
                             * thread until the lock is released.
                             */
                            TimeSpan requestTimeInQ = DateTime.Now.Subtract(wr.WorkingTime);

                            if (requestTimeInQ >= _pool._newThreadTrigger && _pool._currentThreadCount < _pool._maxThreadCount)
                            {
                                /*
                                 * Note - the constructor for ThreadWrapper will update
                                 * pool.currentThreadCount.
                                 */
                                newThread = new ThreadWrapper(_pool, false, _priority, string.Format("{0} (dynamic)", _pool._threadPoolName));

                                /*
                                 * Since the current request we just dequeued is stale,
                                 * everything else behind it in the queue is also stale.
                                 * So reset the timestamps of the remaining pending work
                                 * requests so that we don't start creating threads
                                 * for every subsequent request.
                                 */
                                _pool.ResetWorkRequestTimes();
                            }
                        }
                        else
                        {
                            /*
                             * Should only get here if this is a dynamic thread that
                             * timed out waiting for a work request, or if the pool
                             * is shutting down.
                             */
                            _pool._currentThreadCount--;

                            if (_pool._currentThreadCount == 0)
                            {
                                /*
                                 * Last one out turns off the lights.
                                 */
                                if (_pool.Stopped != null)
                                {
                                    _pool.Stopped();
                                }
                                _pool._stopCompleteEvent.Set();
                            }

                            done = true;
                        }
                    }
                    finally
                    {
                        Monitor.Exit(_pool._syncLock);
                    }

                    // No longer holding pool lock here...

                    if (!done && wr != null)
                    {
                        /*
                         * Check to see if this request has been cancelled while
                         * stuck in the work queue.
                         *
                         * If the work request was pending, mark it processed and proceed
                         * to handle.  Otherwise, the request must have been cancelled
                         * before we plucked it off the request queue.
                         */
                        if (Interlocked.CompareExchange(ref wr.State, WorkRequest.PROCESSED, WorkRequest.PENDING) != WorkRequest.PENDING)
                        {
                            /*
                             * Request was cancelled before we could get here.
                             * Bail out.
                             */
                            continue;
                        }
                        if (newThread != null)
                        {
                            newThread.Start();
                        }

                        /*
                         * Dispatch the work request.
                         */
                        ThreadInfo originalThreadInfo = null;
                        try
                        {
                            /*
                             * Impersonate (as much as possible) what we know about
                             * the thread that issued the work request.
                             */
                            originalThreadInfo = ThreadInfo.Impersonate(wr.ThreadInfo);

                            WorkRequestDelegate targetProc = wr.TargetProc as WorkRequestDelegate;

                            if (targetProc != null)
                            {
                                targetProc(wr.ProcArg, wr.TimeStampStarted);
                            }
                            else
                            {
                                wr.TargetProc.DynamicInvoke(wr.ProcArgs);
                            }
                        }
                        finally
                        {
                            /*
                             * Restore our worker thread's identity.
                             */
                            ThreadInfo.Restore(originalThreadInfo);
                        }
                    }
                }
            }
示例#12
0
            public int State = PENDING;           // The state of this particular request.

            public WorkRequest(WorkRequestDelegate cb, object arg,
                                bool propogateThreadPrincipal, bool propogateCallContext)
            {
                TargetProc = cb;
                ProcArg = arg;
                ProcArgs = null;

                Initialize(propogateThreadPrincipal, propogateCallContext);
            }