如何在BackgroundWorker Dowork进行并行数据处理worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.WorkerSupportsCancellation = true;
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
//////////////////////////////////////////////////
private void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            if (worker.CancellationPending) return;           
            
            foreach (XmlFormat xf in xmlList)
            {
                if (worker.CancellationPending) return;
                switch (xf.method.ToLower())
                {
                    case "upload": upload(xf); break;
                    case "download": download(xf); break;
                    default: return;
                }
            }
           
        }
//////////////////
也就是说,我要在foreach里面,并行处理各个xf,不必等每个xf结束才处理才一个问题,因为怕其中一个任务处理不了,全部挂住了 
所以必须采用并行处理,而不是串行处理. 在每个foreach里面新增一个新线程是可以实现并行的,但是对于BackgroundWorker的事件报告会产生紊乱.所以不知道怎么用?麻烦各位高手献计献策,如果有什么疑问,可以写在回复上 
或者是不是可以通过重载OnDoWork方法,如果可以,又要怎么写呢?谢谢大家 

解决方案 »

  1.   

    我来扯2句
    如果你一定要使用BackgroundWorker 
    那么你在Dowork里面写foreach的时候用异步或者开启新线程,因为你的操作是都要执行,但是不需要等待结果,那么你每一次foreach就异步执行一次那个方法,或者开启个线程执行,由于 
    不管结果,那么invoke了或者thread开始以后,就会执行下一步(这个思路我没有在(BackgroundWorker 里面用过因为如果有你这样的情况我用下面的方法解决,你自己验证下)一般我遇到这类问题就不用BackgroundWorker来做了,因为我觉得他处理复杂的多线程问题时不如自己开启线程来得容易,一般我是自己开线程然后控制,线程多了就用线程池之类
      

  2.   

    准备启用ThreadPool,发现蛮好用的,准备开始用之
      

  3.   


    可是用ThreadPool.RegisterWaitForSingleObject可针对每个线程进行TimerInterval设置吗?
      

  4.   

    还是只是针对所有的进行了Interval进行一次性设置,而不是每个线程.
      

  5.   

    你的操作貌似不需要用到线程同步之类的直接丢线程池里面执行就完了,你为什么会用到TimerInterval呢?
      

  6.   

    额.....是不是你循环开出的线程会用对某个对象独占,然后再执行其他操作= =?,如果是就lock
    我不是很清楚你这里使用定时器的原因,我对你的业务不太了解哈
      

  7.   

    楼主使用BackgroundWorker来实现应该是比较合适的处理方式,BackgroundWorker的实现原理是基于事件的异步处理模式。你在 foreach循环中可以使用单独的线程(Thread)来执行upload或download方法。如果这些方法有执行结果而且需要显示到UI元素上,那么可以调用Control.BeginInvoke或Control.Invoke来跨线程更新UI元素。
    另外,你也可以在foreach循环中试一下实例化新的BackgroundWorker来执行upload或download方法,不过需要注意的是在该处实例化的BackgourndWorker对象线程上下文是在worker_DoWork方法的上下文,不同于UI线程,因此需要调用 Control.BeginInvoke或Control.Invoke方法。下面一些文章可以给楼主排忧解难。
    使用BackgroundWorker组件进行异步操作编程
    http://blog.csdn.net/zhzuo/archive/2008/07/23/2699305.aspx
    实现增强的异步任务执行组件
    http://blog.csdn.net/zhzuo/archive/2008/07/23/2699847.aspx通过多线程为基于 .NET 的应用程序实现响应迅速的用户
    http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/misMultithreading.mspx
    为Windows应用创建简单的异步调用模式
    http://www.microsoft.com/china/MSDN/library/architecture/AsynCallPattern.mspx
      

  8.   

    BackgroundWorker应用问题
    第一个问题:
    如果我事先不知道要定义多少个BackgroundWorker
    必须要通过读取config.xml来定义BackgroundWorker的数量
    比如config.xml内容为下
    task1
    task2
    task3
    通过XML读取这个任务,所以要定义三个BackgroundWorker要如何定义?第二个问题:
    我要执行这三个任务并行处理,又要怎么办,而不是按顺序来执行之?
    也就是task1,task2,task3三个一起执行,不管有没有执行结束?第三个问题:
    如何重载Background使得在BackgroundWoker的OnDoWorker()事件中新加入一个参数?
    第四个问题:还没想好...想好了再continue...
    Thanks!!!
    private BackgroundWorker worker;
    worker = new BackgroundWorker();
    worker.WorkerReportsProgress = true;
    worker.WorkerSupportsCancellation = true;
    worker.DoWork += new DoWorkEventHandler(worker_DoWork);
    worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
    worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
      

  9.   

    使用BackgroundWorker组件进行异步操作编程 
    http://blog.csdn.net/zhzuo/archive/2008/07/23/2699305.aspx 
    实现增强的异步任务执行组件 
    http://blog.csdn.net/zhzuo/archive/2008/07/23/2699847.aspx 通过多线程为基于 .NET 的应用程序实现响应迅速的用户 
    http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/misMultithreading.mspx 
    为Windows应用创建简单的异步调用模式 
    http://www.microsoft.com/china/MSDN/library/architecture/AsynCallPattern.mspx