c# – 使用ThreadPool.QueueUserWorkItem对线程进行排序
我是线程基础知识的新手.
我有一个操作队列要对XML文件执行(节点添加,节点删除等) 1]有’n’xml文件,每个文件使用一个线程池分配一个线程 我想使用线程实现并发和操作顺序(重要). 2]也可以为每个操作分配一个线程并实现可靠性并保持顺序. 在STA模型中我做了类似的事情.. while(queue.count>0){ File f = queue.Dequeue(); //get File from queue OperationList oprlst = getOperationsForFile(f); // will get list-> [a1,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循环 目前正在使用.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(); } 前面的示例是一个非常基本的线程池,但它应该说明需要做什么. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- ajax接收action的数据返回一大串的html代码的问题
- C#图像识别
- 由SEDA,HALF-SYNC/HALF-ASYNC 和PIPELINE AND R
- Flex程序只有两帧,为什么ENTER_FRAME事件不断发
- hybrid computing using a neural network with
- 如何在C#中从plist(xml)读取键值
- C++ operator关键字(重载操作符)的用法详解
- Flash Air Native Extension 开发中遇到的问题整
- vb.net – 在Accord.Net上使用AdaBoost(Boosting
- Ceilometer项目源码分析----ceilometer报警器状态