调用RunWorkerAsync一次,BackgroundWorker的DoWork会不会被调用两次?我在它工作的类中创建了一个后台工作者,但是如果我调用并等到最后一次运行,那么我第二次调用它会执行两次相同的过程我认为bw.DoWork+=privatevoidbutton1_Click有问题(对象发送者,EventArgse){nptest.test.start(“null”,“null”);}namespacenptest{classtest{publicstaticvoidstart(stringstr,stringstrb){if(bw.IsBusy!=true){bw.WorkerSupportsCancellation=true;bw.DoWork+=(obj,e)=>bw_DoWork(str,strb);bw.RunWorkerCompleted+=newRunWorkerCompletedEventHandler(bw_RunWorkerCompleted);bw.RunWorkerAsync();}}privatestaticBackgroundWorkerbw=newBackgroundWorker();privatestaticvoidbw_DoWork(stringstr,stringstrb){System.Windows.Forms.MessageBox.Show("初始化BackgroundWorker");}privatestaticvoidbw_RunWorkerCompleted(objectsender,RunWorkerCompletedEventArgse){if((e.Cancelled==true)){Console.WriteLine("Canceled");}elseif(!(e.Error==null)){Console.WriteLine("错误:"+e.Error.Message);}bw.Dispose();}}}问题已解决classtest{privatestaticListarguments=newList();//使用程序启动进行初始化publicstaticvoidbwinitializing(){bw.WorkerSupportsCancellation=true;bw.DoWork+=newDoWorkEventHandler(bw_DoWork);bw.RunWorkerCompleted+=newRunWorkerCompletedEventHandler(bw_RunWorkerCompleted);}publicstaticvoidstart(stringstr,stringstrb){if(bw.IsBusy!=true){arguments.Clear();arguments.Add(str);arguments.Add(strb);bw.RunWorkerAsync(参数);}}privatestaticBackgroundWorkerbw=newBackgroundWorker();privatestaticvoidbw_DoWork(objectsender,DoWorkEventArgse){Listgenericlist=e.ArgumentasList;System.Windows.Forms.MessageBox.Show("BackgroundWorker"+genericlist[0]);我怀疑无意中添加了多个DoWork事件,即,每次调用start方法时,它都会注册一个新的DoWork事件处理程序。这会添加但不会替换现有的DoWork处理程序。然后会有多个DoWork处理程序被调用后续时间..1、2、3等。//创建一个新委托并添加一个新处理程序bw.DoWork+=(obj,e)=>bw_DoWork(str,strb);我建议不要在这里使用闭包,而只是使用方法组(隐式转换为委托),然后将数据传递给RunWorkerAsync调用(有一种形式可以接受数据参数)。RunWorkerCompleted+=行没有这个问题,因为它传递了来自方法组的委托(保证始终评估同一个委托对象1)。所以重复+=对该行的调用将替换处理程序。示例:classMyData{publicstringStrA{get;放;}}//这些只需要设置一次(为了清楚起见)。//然而,如果它们被多次调用,现在就“ok”了//因为委托是相同的,所以+=将//充当替换(因为它用自己替换了之前的委托)。bw.WorkerSupportsCancellation=true;bw.DoWork+=bw_DoWork;bw.RunWorkerCompleted+=bw_RunWorkerCompleted;//通过参数传递数据bw.RunWorkerAsync(newMyData{StrA=str,});voidbw_DoWork(objectsender,DoWorkEventArgse){vardata=(MyData)e.Argument;varstr=data.StrA;//stuff}1我不确定它是否保证引用相等,但使用这种方法允许从方法组的委托稳定调用+=和-=,即使是通过newDelegateType(MethodGroup)也是如此。WRT。我在主帖中的评论:如果UI元素是从从未创建它们的线程访问的,那么就会出现有趣的“跨线程操作异常”。我相信消息框的这种使用是“好的”(当不是由另一个线程的所有者创建时),但是在BackgroundWorker的DoWork中访问UI通常是可疑的。另外,不要在这里调用bw.Dispose();用拥有的容器或上下文处理它。在这种情况下,它看起来很好而且是良性的,但前提是BGW实例永远不会被再次使用。从事件处理程序调用它也是可疑的,因为BGW仍然“活着”。我遇到了与上述评论者“Power-Mosfet”相同的问题最后,添加一个新的BackgroundWorker()然后分配给全局bw值将解决我的问题。代码是,改成:privateBackgroundWorkergBgwDownload;privatevoidyourFunction_bw(xxx){//创建后台线程gBgwDownload.DoWork+=bgwDownload_DoWork;gBgwDownload.RunWorkerCompleted+=bgwDownload_RunWorkerCompleted;//省略了一些代码gBgwDownload.RunWorkerAsync(To:privateBackgroundWorkergBgwDownload;privatevoidyourFunction_bw(xxx){//创建一个后台线程gBgwDownload=newBackgroundWorker();/*添加这一行将解决问题*/gBgwDownload.DoWork+=bgwDownload_DoWork;gBgwDownload.RunWorkerCompleted+_RunbgwDownload//省略了一些代码gBgwDownload.RunWorkerAsync(paraObj);}还有一个原因,如果是通过compnentUI属性生成的,自己注册的话,在其生成的代码中寻找DoWorkEventHandlerInitializeComponent()因为如果你再次注册,它不会覆盖前一个,但会添加另一个事件,并将被调用两次。在我的例子中,BackgroundWorker运行了两次,因为在我的表单的构造函数类中,我声明了DoWork、ProgressChanged和RunWorkerCompleted事件处理程序,但它是VisualStudio2013已经在这个表单类语句的设计器部分使用了。所以,我只是删除了我的语句并且它工作正常。谢谢……这段代码工作正常……为后台工作者创建新实例是个好主意……现在我们可以在for/while循环中调用这个函数,并且可以运行多个后台工作者进程。当按钮点击完成时,我这样编码..没有分配主线程流..多个进程将运行回来..我只是使用消息框弹出..但是我们可以在时间进程中运行“bgwDownload_DoWork”函数..将创建多个进程......我们不需要检查BackgroundWorker是否忙......privatevoidbutton1_Click(objectsender,EventArgse){for(inti=0;i我今天遇到了这个问题,我让一个后台工作者长时间执行在运行任务的弹出窗口上,我注意到每次显示表单时都会多次调用后台工作者RunWorkerCompleted事件。我的问题是表单是'在我关闭它之后处理,这意味着每次我显示表单时,它每次都会添加另一个处理程序。完成后处理表单解决了我的问题。我只想在这里提及它,因为当我为我的问题寻找解决方案时情况,碰到这个页面,上面是C#学习教程:RunWorkerAsync调用一次,BackgroundWorker的DoWork会被调用两次?分享的所有内容,如果对你有用,需要了解更多C#学习教程,希望大家多多关注---本文收集自网络,不代表立场,如涉及侵权,敬请谅解点击右侧联系管理员删除。如需转载请注明出处:
