internal static void JobFinished(WebRequestThread aThread) { lock (iLock) { iWorkPool.Remove(aThread); iFreePool.Push(aThread); if (iFreePool.Count == 1) { iHasFreeThreads.Set(); } Trace.WriteLine(Trace.kCore, "WebRequestPool.JobFinished: iFreePool.Count=" + iFreePool.Count + ", iWorkPool.Count=" + iWorkPool.Count); } }
public static void QueueJob(IJob aJob) { if (!aJob.HasWork()) return; WebRequestThread t = null; while (t == null) { List<WebRequestThread> threadsToDelete = new List<WebRequestThread>(); // get a free thread from the pool lock (iLock) { // remove any excess threads from the free pool while (iFreePool.Count > kMinNumThreads) { threadsToDelete.Add(iFreePool.Pop()); } // get a free thread, if available if (iFreePool.Count > 0) { t = iFreePool.Pop(); Trace.WriteLine(Trace.kCore, "WebRequestPool.QueueJob: popped iFreePool new count = " + iFreePool.Count); if (iFreePool.Count == 0) { iHasFreeThreads.Reset(); } } } // cleanup excess threads foreach (WebRequestThread toDelete in threadsToDelete) { toDelete.Dispose(); Trace.WriteLine(Trace.kCore, "WebRequestPool.QueueJob: deleted WebRequestThread"); } // if no threads are free, create a new one if allowed if (t == null && kCanCreateThreads) { try { t = new WebRequestThread(); Trace.WriteLine(Trace.kCore, "WebRequestPool.QueueJob: created WebRequestThread"); } catch (OutOfMemoryException) { Trace.WriteLine(Trace.kCore, "WebRequestPool.QueueJob: failed to create WebRequestThread"); } } // wait for a free thread if there are none available and could not create one if (t == null) { Trace.WriteLine(Trace.kCore, "WebRequestPool.QueueJob: no threads available, waiting..."); iHasFreeThreads.WaitOne(); } } // add the thread to the work pool lock (iLock) { iWorkPool.Add(t); Trace.WriteLine(Trace.kCore, "WebRequestPool.QueueJob: iFreePool.Count=" + iFreePool.Count + ", iWorkPool.Count=" + iWorkPool.Count); } t.Start(aJob); }