重启背景工作者

时间:2009-06-17 06:59:33

标签: c# .net backgroundworker

有没有办法直接“重启”后台工作人员? 调用CancelAsync()后跟RunWorkerAsync()显然不会这样做,因为他们的名字暗示。

背景资料: 我有一个后台工作者,在我的.net 2.0 Windows窗体应用程序中计算总数。 每当用户修改任何属于此总数的值时,我都想重新启动后台工作程序,以防它运行,以便直接考虑最新值。

5 个答案:

答案 0 :(得分:8)

backgriound工作本身并没有做任何改变。

当您调用bgw.CancelAsync时,它会在后台工作程序上设置一个标记,您需要在DoWork处理程序中检查自己。

类似的东西:

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;
    }

}

答案 1 :(得分:2)

有两种选择,一切都取决于你想要给这只猫涂上白色的方法:

如果您想继续使用BackgroundWorker,那么您需要尊重已建立的模型,即“进度敏感度”之一。 DoWork内的内容显然需要始终知道待处理的取消是否到期(即,DoWork循环中需要进行一定数量的轮询)。 / p>

如果您的计算代码是单片的并且您不想弄乱它,那么请不要使用BackgroundWorker,而是启动您自己的线程 - 这样您就可以强制杀死它,如果需要的话

答案 2 :(得分:0)

您可以为更改值的控件挂钩change事件处理程序,并在处理程序中执行以下操作:

if(!bgWrkr.IsBusy)
     //start worker
else if(!bgWrkr.CancellationPending)
  bgWrkr.CancelAsync();

希望它可以帮到你!

答案 3 :(得分:0)

我想让我的请求继续运行,但不再关心结果。我覆盖后台工作者的值(我忙的微调器正在使用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);
    }

答案 4 :(得分:0)

该方法可以帮助某人...我创建了一个函数来用一种方法重置backgroundworker。我用它来定期执行任务。

通过创建Task,可以使用CancelAsync停止backgroundworker并在Task中重新启动。如OP所述,不执行任务将在取消背景工作之前再次启动它。

唯一的要求是您的代码通过某个循环运行,该循环每隔一段时间(CheckPerMilliseconds检查一次CancellationPending。

private void ResetBackgroundWorker()
{
    backgroundWorker.CancelAsync();

    Task taskStart = Task.Run(() => 
    {
        Thread.Sleep(CheckPerMilliseconds);
        backgroundWorker.RunWorkerAsync();
    });
}

在后台工作人员内部,我使用了一个for循环来检查CancellationPending。

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);
        }
    }
}