我是线程基础知识的新手. 我有一个操作队列要对XML文件执行(节点添加,节点删除等) 1]有’n’xml文件,每个文件使用一个线程池分配一个线程 ThreadPool.QueueUserWorkItem来做那些文件操作. 我
我有一个操作队列要对XML文件执行(节点添加,节点删除等)
1]有’n’xml文件,每个文件使用一个线程池分配一个线程
ThreadPool.QueueUserWorkItem来做那些文件操作.
我想使用线程实现并发和操作顺序(重要).
例如:假设要对文件“A.xml”执行操作[a1,a2,a3,a4,a5]
和操作[b1,b2,b3,b4,b5,b6,b7]将在文件“B.xml”上执行…..
我想分配线程,以便我可以执行这些操作
相同的顺序,也同时(因为文件不同).
2]也可以为每个操作分配一个线程并实现可靠性并保持顺序.
在STA模型中我做了类似的事情..
while(queue.count>0){ File f = queue.Dequeue(); //get File from queue OperationList oprlst = getOperationsForFile(f); // will get list-> [a1,a2,a3,a4,a5] for each Operation oprn in oprlst { performOperation(f,oprn) //in MTA i want to wait till operation "a1" completes and then operation "a2" will //start.making threads wait till file is in use or operation a(i) is in use. } }
我想与操作订单保存同时执行此操作.
线程(操作)可以在一个文件上等待……但是
不同的操作需要不同的执行时间
我尝试了AutoResetEvent和WaitHandle.WaitAll(..),但它做了while循环
停止直到所有’a(i)’操作结束……我希望a(i)和b(j)同时执行.
(但在(i)和b(j)中排序)
目前正在使用.net 2.0.
这非常相似,是Question问题的一部分
您应该避免在ThreadPool线程中使用诸如Monitor锁和WaitHandle结构之类的线程阻塞技术,因为这些线程被其他进程使用.您需要使用基于单个文件的线程.如果单个文件没有花费那么长的时间来处理(并且你没有太多的文件),那么ThreadPool将会工作.ThreadPool实现
您可以在以文件为中心的方法上使用EnqueueUserWorkItem ……这样的事情:
private void ProcessFile(Object data) { File f = (File)data; foreach(Operation oprn in getOperationsForFile(f)) { performOperation(f, oprn); } }
然后在处理文件的代码中,执行以下操作:
while(queue.Count > 0) { ThreadPool.QueueUserWorkItem(new WaitCallback(ProcessFile), queue.Dequeue()); }
如果你需要你的调用线程阻塞直到它们都完整,那么WaitHandle就可以了(因为你阻塞了你自己的线程,而不是ThreadPool线程).但是,您必须创建一个小的有效负载类来将其传递给线程:
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 > 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);
线程实现
但是,如果您有大量文件(或者文件可能需要花费大量时间来处理),那么创建自己的线程是个更好的主意.这也可以让你省略WaitHandles.
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 > 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 < 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 < threads.Length; i++) { threads[i].Join(); }
前面的示例是一个非常基本的线程池,但它应该说明需要做什么.