private void ExportFilesDataWithImpersonation(List <string> files, bool isGPO) { // insert relation related to the files already seen. // add subdirectory / sub file is the permission is not inherited BlockingQueue <string> queue = new BlockingQueue <string>(200); int numberOfThread = 20; Thread[] threads = new Thread[numberOfThread]; try { ThreadStart threadFunction = () => { for (; ;) { string fileName = null; if (!queue.Dequeue(out fileName)) { break; } // function is safe and will never trigger an exception if (isGPO) { RelationFactory.AnalyzeGPO(fileName); } else { RelationFactory.AnalyzeFile(fileName); } } Trace.WriteLine("Consumer quitting"); }; // Consumers for (int i = 0; i < numberOfThread; i++) { threads[i] = new Thread(threadFunction); threads[i].Start(); } // do it in parallele (else time *6 !) foreach (string file in files) { queue.Enqueue(file); } queue.Quit(); Trace.WriteLine("insert file completed. Waiting for worker thread to complete"); for (int i = 0; i < numberOfThread; i++) { threads[i].Join(); } Trace.WriteLine("Done insert file"); } finally { queue.Quit(); for (int i = 0; i < numberOfThread; i++) { if (threads[i] != null) { if (threads[i].ThreadState == System.Threading.ThreadState.Running) { threads[i].Abort(); } } } } }