当前位置: 首页 > 编程语言 > C#

后台不忙分享

时间:2023-04-11 03:00:49 C#

后台不忙for(多做几次){while(backgroundWorker1.IsBusy&&backgroundWorker2.IsBusy&&backgroundWorker3.IsBusy&&backgroundWorker4.IsBusy&&backgroundWorker5.IsBusy){System.Threading.Thread.Sleep(0001);}if(!backgroundWorker1.IsBusy){backgroundWorker1.RunWorkerAsync();}elseif(!backgroundWorker2.IsBusy){backgroundWorker2.RunWorkerAsync();elseif(!backgroundWorker3.IsBusy){backgroundWorker3.RunWorkerAsync();}elseif(!backgroundWorker4.IsBusy){backgroundWorker4.RunWorkerAsync();}elseif(!backgroundWorker5.IsBusy){backgroundWorker5.RunWorkerAsync();运行它五次(每个BG工作一次)并卡住了一段时间。后台不忙了?如何查看可用性?注意:有5个工作线程,这确保它们都不会停止,它们总是被分配工作。但是他们拒绝告诉我它什么时候可用,我认为这将有一个简单的解决方案..–[编辑请求]–实际上它只是一个虚拟参数,我删除了它而忘了取出它,我只是用它来调用dowork,谁做肮脏的工作:privatevoidbackgroundWorker1_DoWork(objectsender,DoWorkEventArgse){timeconsumingfunction(publicstring);}耗时函数结束。在调试器中进入它并一次一行地运行它,直到它结束并到达最后的'}'。那意味着它结束了,对吧?--[编辑答案]---它通过替换行System.Threading.Thread.Sleep(0001)来工作;与Application.DoEvents()相同;我猜它会在后台运行,但没有收到任何答复并且IsBusy标签没有更新。谢谢大家,很好的回答,帮助很大!您的循环导致死锁,BGW无法完成它。问题是在UI线程上引发的RunWorkerCompleted事件。那个BGW魔法需要UI线程空闲,它必须启动消息循环。问题是,UI线程没有空闲,也没有发送消息,而是卡在了for循环中。因此,事件处理程序无法运行并且IsBusy保持为真。您需要以不同的方式执行此操作。使用RunWorkerCompleted事件运行通常在此for循环之后运行的代码。抵制在循环中调用Application.DoEvents()的所有诱惑。我建议您更改代码以处理RunWorkerCompleted事件,以便在BackgroundWorker完成其工作时收到通知。官方文档中有一个如何使用BackgroundWorker的示例。我在后台工作人员遇到了同样的问题,得出的结论是,如果你在循环中使用sleep()那么它就会卡住。您可以使用RunWorkerCompleted事件并设置一个布尔标志来指示每个工作人员何时完成。或者如果你想中止线程,你是否可以使用线程而不是后台工作者。但是,您无法轻松使用后台工作人员提供的事件。您的主线程需要发送Windows消息(在while循环中调用Application.DoEvents,或者更好的是,使用Systems.Windows.Forms.Timer而不是循环)。如果您不获取Windows消息,后台工作人员的“已完成”通知将不会被处理,因此状态将保持忙碌。我有一个类似的问题,我所做的就是用try...catch...和finally...语句包装主函数。.IsBusy只是意味着后台工作人员实际上正在做某事。它会很忙,直到“某事”完成。似乎“某事”没有完成,让你的后台工作人员很忙。因此,如果您能解释什么是“某事”以及在主线程上执行“某事”可能需要多长时间,那将会很有帮助。问题是,无论您在worker.RunWorkerAsync()中做什么,都永远不会完成。也许在您的DoWork事件中定义了一些无限循环或类似的东西。这是一个工作示例,它选择下一个免费工作人员:usingSystem;使用System.Collections.Generic;使用System.ComponentModel;使用系统线程;namespaceConsoleApplication1{classProgram{privatestaticList_Workers;staticvoidMain(string[]args){_Workers=newList();for(inti=0;iDoSomething(freeWorker.Index,rand.Next(500,2000))));}else{Console.WriteLine("没有可用的免费工人!");Console.WriteLine("等待免费一个...");WaitForFreeOne();}}}privatestaticMyWorkerGetFreeWorker(){foreach(varworkerin_Workers){if(!worker.Worker.IsBusy)returnworker;}返回空值;}privatestaticvoidWaitForFreeOne(){while(true){foreach(varworkerin_Workers){if(!worker.Worker.IsBusy)return;}Thread.Sleep(1);}}privatestaticMyWorkerCreateDefaultWorker(intindex){varworker=newMyWorker(index);worker.Worker.DoWork+=(sender,e)=>((Action)e.Argument).Invoke();worker.Worker.RunWorkerCompleted+=(sender,e)=>Console.WriteLine("Job在worker中完成"+worker.Index);返回工人;}staticvoidDoSomething(intindex,inttimeout){Console.WriteLine("Worker{1}开始工作{0}ms",timeout,index);线程。睡眠(超时);}}publicclassMyWorker{publicintIndex{get;私有集;}publicBackgroundWorkerWorker{get;私有集;}publicMyWorker(intindex){Index=index;Worker=newBackgroundWorker();下面的示例给出了您的问题的有效解决方案正如HansPassant解释的那样,您的代码在后台工作程序中运行,但每个线程的RunWorkerCompleted仅在ui线程中的Evaluate上运行。为此,您将请求放入线程的UI队列(ThreadPool)中。这样,UI会评估RunWorkerCompletedEvent,然后跳回代码。以上就是C#学习教程:后台忙不停的分享所有内容。如果对大家有用,需要进一步了解C#学习教程,希望大家多多关注——for(inti=0;i{while(backgroundWorker1.IsBusy&&backgroundWorker2.IsBusy){System.Threading.Thread.Sleep(0);}//所有线程结束后正在执行的代码。myCode();}));如果(!backgroundWorker1.IsBusy){backgroundWorker1.RunWorkerAsync();}elseif(!backgroundWorker2.IsBusy){backgroundWorker2.RunWorkerAsync();}}本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: