static public void ReapUnusedPoolEntries() { for (int i = processorPool.Count - 1; i > -1; i--) { RequestProcessorPoolEntry pe = processorPool[i]; if (pe.MyCurrentState == RequestProcessorPoolEntry.EntryState.Free && pe.EmptyLoopCount >= MAX_NOWORK_LOOPS) { lock (poolLock) { processorPool.RemoveAt(i); pe.Dispose(); } } //look for invalid state pool entries if (pe.MyCurrentState == RequestProcessorPoolEntry.EntryState.Working && pe.MyProcessorObject.MyCurrentRequest == null) { lock (poolLock) { if (pe.MyProcessorObject.MyCurrentRequest == null) { ReleaseRequestProcessor(pe); } } } } }
public void ThreadWatchQueue() { while (!exitThread) { if (paused) { //_myWaitHandle.WaitOne(-1); _myWaitHandle.WaitOne(10000); } try { if (queue.Count == 0) { //reap any pool entries without work AsyncRequestProcessor.RequestProcessorThreadPool.ReapUnusedPoolEntries(); this.PauseWatching(); _myWaitHandle.WaitOne(5000); continue; } } catch (Exception ex) { System.Diagnostics.Debug.Write("Error in Reaper"); continue; } RequestProcessorPoolEntry poolEntry = AsyncRequestProcessor.RequestProcessorThreadPool.GetRequestProcessor(); if (poolEntry == null) { continue; } QueuedRequest request = null; lock (queue) { if (queue.Count > 0) { request = queue.Dequeue(); } } if (request != null) { poolEntry.MyProcessorObject.MyCurrentRequest = request; poolEntry.MyProcessorObject.ResumeRequestProcessing(); if (poolEntry.MyThread.ThreadState == ThreadState.Unstarted) { try { poolEntry.MyThread.Start(); } catch { } } } else { AsyncRequestProcessor.RequestProcessorThreadPool.ReleaseRequestProcessor(poolEntry); } } AsyncRequestProcessor.RequestProcessorThreadPool.ClearPool(); }
/// <summary> /// Checks a processor out of the pool /// </summary> /// <returns></returns> static public RequestProcessorPoolEntry GetRequestProcessor() { RequestProcessorPoolEntry retval = null; lock (poolLock) { for (int i = 0; i < processorPool.Count; i++) { if (processorPool[i].MyCurrentState == RequestProcessorPoolEntry.EntryState.Free || ( processorPool[i].MyCurrentState == RequestProcessorPoolEntry.EntryState.Working && processorPool[i].MyProcessorObject.MyCurrentRequest == null && processorPool[i].MyThread.ThreadState == ThreadState.Unstarted) ) { retval = processorPool[i]; break; } } if (retval == null && processorPool.Count < MAX_POOL_SIZE) { retval = new RequestProcessorPoolEntry(); AsyncRequestProcessor proc = AsyncRequestProcessor.CreateProcessor(); proc.MyPoolEntry = retval; retval.MyProcessorObject = proc; retval.MyThread = new Thread(new ThreadStart(proc.ThreadStartRequestProcessing)); processorPool.Add(retval); } if (retval != null) { retval.MyCurrentState = RequestProcessorPoolEntry.EntryState.Working; } } return(retval); }
/// <summary> /// Entry point for Threaded Processing /// </summary> public void ThreadStartRequestProcessing() { while (!ExitFlag || MyCurrentRequest != null) { if (MyCurrentRequest == null || MyCurrentRequest.Request == null) { if (MyPoolEntry.EmptyLoopCount < Int32.MaxValue) { MyPoolEntry.EmptyLoopCount++; } Waiting = true; _myWaitHandle.WaitOne(-1); Waiting = false; continue; } HttpWebRequest request = null; if (MyCurrentRequest != null && MyCurrentRequest.Request != null) { request = MyCurrentRequest.Request; } MyPoolEntry.EmptyLoopCount = 0; try { using (HttpWebResponse response = request.GetResponse() as HttpWebResponse) { Stream resultStream = response.GetResponseStream(); RequestResult result = MyCurrentRequest.AsyncResultHandle.AsyncState as RequestResult; if (null == result) { result = new RequestResult(); MyCurrentRequest.AsyncResultHandle.AsyncState = result; } result.ContentType = response.ContentType; result.CharacterSet = response.CharacterSet; result.ContentEncoding = response.ContentEncoding; result.Key = MyCurrentRequest.RequestId; string jsMIMEs = "application/json|application/x-javascript|application/javascript|text/ecmascript|application/ecmascript|text/jscript|text/vbscript|"; if (!string.IsNullOrEmpty(response.ContentType) && response.ContentType.Contains("text") || jsMIMEs.Contains(response.ContentType.ToLower())) { StreamReader reader = new StreamReader(resultStream); result.ResponseString = reader.ReadToEnd(); } else { BinaryReader br = new BinaryReader(resultStream); long contentLength = response.ContentLength; int maxBytes = 2048; if (contentLength > maxBytes) { return; } else { int arLen = Convert.ToInt32(Math.Min(contentLength, maxBytes)); byte[] b = new byte[arLen]; int read = br.Read(b, 0, arLen); //todo error check result.ResponseData = b; } } response.Close(); resultStream.Close(); } MyCurrentRequest.AsyncResultHandle.CompleteRequest(); } catch (Exception ex) { RequestResult result = MyCurrentRequest.AsyncResultHandle.AsyncState as RequestResult; if (null == result) { result = new RequestResult(); MyCurrentRequest.AsyncResultHandle.AsyncState = result; } result.ResponseCode = 500; result.InternalException = ex; System.Diagnostics.Debug.WriteLine("Error processing: " + ex.Message); System.Diagnostics.Debug.WriteLine("ReqID: " + MyCurrentRequest.RequestId); System.Diagnostics.Debug.WriteLine("Err Request: " + MyCurrentRequest.Request.RequestUri.ToString()); System.Diagnostics.Debug.WriteLine(ex.StackTrace); MyCurrentRequest.AsyncResultHandle.CompleteRequest(); //OnResponseError(this.Result); } finally { MyCurrentRequest = null; if (MyPoolEntry != null) { AsyncRequestProcessor.RequestProcessorThreadPool.ReleaseRequestProcessor(MyPoolEntry); } } } //cleanup MyPoolEntry = null; }
/// <summary> /// Releases the processor back to the pool /// </summary> /// <param name="processor"></param> static public void ReleaseRequestProcessor(RequestProcessorPoolEntry processor) { processor.MyCurrentState = RequestProcessorPoolEntry.EntryState.Free; }