public bool PostRequest(WorkRequestDelegate cb, object state, out IWorkRequest reqStatus) { WorkRequest request = new WorkRequest(cb, state, _propogateThreadPrincipal, _propogateCallContext); reqStatus = request; return(PostRequest(request)); }
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); }
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); }
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 ); }
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); }
public bool PostRequest( WorkRequestDelegate cb, object state ) { IWorkRequest notUsed; return PostRequest(cb, state, out notUsed); }
// Overloads for the early bound WorkRequestDelegate-based targets. // public bool PostRequest( WorkRequestDelegate cb ) { return PostRequest(cb, (object)null); }
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)); }
public bool PostRequest(WorkRequestDelegate cb, object state) { IWorkRequest notUsed; return(PostRequest(cb, state, out notUsed)); }
// Overloads for the early bound WorkRequestDelegate-based targets. // public bool PostRequest(WorkRequestDelegate cb) { return(PostRequest(cb, (object)null)); }
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); } } } }