Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>You should avoid using thread blocking techniques like <code>Monitor</code> locks and <code>WaitHandle</code> structures in <code>ThreadPool</code> threads, since those threads are used by other processes. You need to have your threading be based around individual files. If an individual file doesn't take that long to process (and you don't have too many files), then the <code>ThreadPool</code> will work.</p> <h3>ThreadPool Implementation</h3> <p>You could just use <code>EnqueueUserWorkItem</code> on a file-centric method...something like this:</p> <pre><code>private void ProcessFile(Object data) { File f = (File)data; foreach(Operation oprn in getOperationsForFile(f)) { performOperation(f, oprn); } } </code></pre> <p>Then in your code that processes the files, do this:</p> <pre><code>while(queue.Count &gt; 0) { ThreadPool.QueueUserWorkItem(new WaitCallback(ProcessFile), queue.Dequeue()); } </code></pre> <p>If you need your calling thread to block until they are all complete, then a <code>WaitHandle</code> is OK (since you're blocking your own thread, <em>not</em> the <code>ThreadPool</code> thread). You will, however, have to create a small payload class to pass it to the thread:</p> <pre><code>private class Payload { public File File; public AutoResetEvent Handle; } private void ProcessFile(Object data) { Payload p = (Payload)data; foreach(Operation oprn in getOperationsForFile(p.File)) { performOperation(f, oprn); } p.Handle.Set(); } ... WaitHandle[] handles = new WaitHandle[queue.Count]; int index = 0; while(queue.Count &gt; 0) { handles[index] = new AutoResetEvent(); Payload p = new Payload(); p.File = queue.Dequeue(); p.Handle = handles[index]; ThreadPool.QueueUserWorkItem(new WaitCallback(ProcessFile), p); index++; } WaitHandle.WaitAll(handles); </code></pre> <h3>Thread Implementation</h3> <p>If, however, you have a large number of files (or it may take a significant amount of time for your files to process), then creating your own threads is a better idea. This also allows you to get away with omitting the <code>WaitHandle</code>s.</p> <pre><code>private void ProcessFile(File f) { foreach(Operation oprn in getOperationsForFile(f)) { performOperation(f, oprn); } p.Handle.Set(); } private object queueLock = new object(); private void ThreadProc() { bool okToContinue = true; while(okToContinue) { File f = null; lock(queueLock) { if(queue.Count &gt; 0) { f = queue.Dequeue(); } else { f = null; } } if(f != null) { ProcessFile(f); } else { okToContinue = false; } } } ... Thread[] threads = new Thread[20]; // arbitrary number, choose the size that works for(int i = 0; i &lt; threads.Length; i++) { threads[i] = new Thread(new ThreadStart(ThreadProc)); thread[i].Start(); } //if you need to wait for them to complete, then use the following loop: for(int i = 0; i &lt; threads.Length; i++) { threads[i].Join(); } </code></pre> <p>The preceding example is a <em>very</em> rudimentary thread pool, but it should illustrate what needs to be done.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload