C# 重启后台工作者
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1005480/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Restart background worker
提问by Marc
Is there a way to directly "restart" a background worker? Calling CancelAsync() followed by RunWorkerAsync() clearly won't do it as their names imply.
有没有办法直接“重启”后台工作人员?调用 CancelAsync() 后跟 RunWorkerAsync() 显然不会像它们的名字暗示的那样。
Background info: I have a background worker which calculates a total in my .net 2.0 Windows Forms app. Whenever the user modifies any value which is part of this total I'd like to restart the background worker in case it would be running so that directly the latest values are considered.
背景信息:我有一个后台工作人员,它在我的 .net 2.0 Windows 窗体应用程序中计算总数。每当用户修改属于此总数的任何值时,我想重新启动后台工作程序,以防它正在运行,以便直接考虑最新值。
采纳答案by Pondidum
The backgriound work itself does not do any cancleing.
背景工作本身不做任何取消。
When you call bgw.CancelAsync
it sets a flag on the background worker that you need to check yourself in the DoWork handler.
当您调用bgw.CancelAsync
它时,会在后台工作人员上设置一个标志,您需要在 DoWork 处理程序中检查自己。
something like:
就像是:
bool _restart = false;
private void button1_Click(object sender, EventArgs e)
{
bgw.CancelAsync();
_restart = true;
}
private void bgw_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i < 300; i++)
{
if (bgw.CancellationPending)
{
break;
}
//time consuming calculation
}
}
private void bgw_WorkComplete(object sender, eventargs e) //no ide to hand not sure on name/args
{
if (_restart)
{
bgw.RunWorkerAsync();
_restart = false;
}
}
回答by TheVillageIdiot
You can hook the change event handler for the controls in which the values are changed and do the following in the handler:
您可以为更改了值的控件挂钩更改事件处理程序,并在处理程序中执行以下操作:
if(!bgWrkr.IsBusy)
//start worker
else if(!bgWrkr.CancellationPending)
bgWrkr.CancelAsync();
Hope it helps you!
希望对你有帮助!
回答by Eric Smith
There are a couple of options, it all depends on how you want to skin this cat:
有几种选择,这完全取决于你想如何给这只猫剥皮:
If you want to continue to use BackgroundWorker
, then you need to respect the model that has been established, that is, one of "progress sensitivity". The stuff inside DoWork
is clearly required to always be aware of whether or not the a pending cancellation is due (i.e., there needs to be a certain amount of polling taking place in your DoWork
loop).
如果你想继续使用BackgroundWorker
,那么你需要尊重已经建立的模型,即“进步敏感性”之一。里面的东西DoWork
显然需要始终知道一个挂起的取消是否到期(即,需要在您的DoWork
循环中进行一定数量的轮询)。
If your calculation code is monolithic and you don't want to mess with it, then don't use BackgroundWorker
, but rather fire up your own thread--this way you can forcefully kill it if needs be.
如果您的计算代码是整体的并且您不想弄乱它,那么不要使用BackgroundWorker
,而是启动您自己的线程——这样您就可以在需要时强行杀死它。
回答by Jacob Brewer
I want to leave my requests running, but no longer care about the results. I override the value of the background worker (my busy spinner is using the isBusy flag).
我想让我的请求继续运行,但不再关心结果。我覆盖了后台工作人员的值(我忙碌的微调器正在使用 isBusy 标志)。
private void SearchWorkerCreate() {
this.searchWorker = new BackgroundWorker();
this.searchWorker.DoWork += this.SearchWorkerWork;
this.searchWorker.RunWorkerCompleted += this.SearchWorkerFinish;
}
private void SearchWorkerStart(string criteria){
if(this.searchWorker.IsBusy){
this.SearchWorkerCreate();
}
this.searchWorker.RunWorkerAsync(criteria);
this.OnPropertyChanged(() => this.IsBusy);
this.OnPropertyChanged(() => this.IsIdle);
}
回答by Jannick Breunis
May this method help someone... I've created a function to reset the backgroundworker in one method. I use it for task to do periodically.
可能这种方法可以帮助某人......我已经创建了一个函数来以一种方法重置后台工作人员。我将它用于定期执行的任务。
By creating a Task
, the backgroundworker is can be stopped with the CancelAsync
and restarted inside the Task. Not making a Task wil start the backgroundworker again before it is cancelled, as the OP describes.
通过创建Task
,后台工作器可以CancelAsync
在任务中停止并重新启动。正如 OP 所描述的那样,不执行任务将在取消任务之前再次启动后台工作程序。
The only requirement is that your code runs through some loop, which checks the CancellationPending every period of time (CheckPerMilliseconds
).
唯一的要求是您的代码运行通过某个循环,它会在每个时间段 ( CheckPerMilliseconds
) 中检查 CancellationPending 。
private void ResetBackgroundWorker()
{
backgroundWorker.CancelAsync();
Task taskStart = Task.Run(() =>
{
Thread.Sleep(CheckPerMilliseconds);
backgroundWorker.RunWorkerAsync();
});
}
Inside the backgroundworker I use a for-loop that checks the CancellationPending.
在后台工作人员中,我使用一个检查 CancellationPending 的 for 循环。
private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
while(true)
{
if (backgroundWorker.CancellationPending)
{
return;
}
//Do something you want to do periodically.
for (int i = 0; i < minutesToDoTask * 60; i++)
{
if (backgroundWorker.CancellationPending)
{
return;
}
Thread.Sleep(CheckPerMilliseconds);
}
}
}