BackgroundWorker Suspend

本文关键字:Suspend BackgroundWorker | 更新日期: 2023-09-27 17:51:16

我有一个BackgroundWorker _worker

void _worker_DoWork(object sender, DoWorkEventArgs e)
{
    _timer = new System.Timers.Timer();
    _timer.Elapsed += new System.Timers.ElapsedEventHandler(_timer_Elapsed);
    _timer.Interval = 5000;
    _timer.Start();
}

当它到达_timer.Start()行时,它认为它已经完成了,因此触发了RunWorkerCompleted event

我不希望它完成,直到_timer.Interval时间已经达到,_timer Elapsed event已经触发:

void _timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    for (int i = 1; i < 20; i++)
    {
        if (listBox1.InvokeRequired)
            listBox1.Invoke((Action)(() => listBox1.Items.Add("Do Things Thread")));
        else
            listBox1.Items.Add("Do Things Completed");
        _worker.ReportProgress((int)(((decimal)i / (decimal)20) * 100));
        Thread.Sleep(1000);
    }
    _timer.Stop();
}

因为我需要BackgroundWorker报告一些进度。

我该怎么做呢?我需要它运行在不同的thread .

BackgroundWorker Suspend

让我们来总结一下讨论和解决方案。

System.Timers。Timer将自动为您执行Timer事件,除非您提供一个同步对象,如MSDN中所述:

如果SynchronizingObject属性为空,则经过的事件为空在ThreadPool线程上引发。如果处理已经过的事件持续时间超过Interval,则事件可能会在另一个事件上再次引发ThreadPool线程。在这种情况下,事件处理程序应该是可重入。

这意味着后台工作线程变成了多余的。你可以简单地让你的计时器事件代码按原样运行(因为它使用调用来与UI交互)。

表示如果这些事件需要很长时间,则它们可以并发运行。但是,您当然可以在事件回调中停止和启动计时器。

您的_timer_Elapsed事件在不同的线程上。当控制流通过_worker_DoWork函数时,timer实例就会过期。计时器对象变量的作用域被限制在函数中,因此它不会以这种方式工作。

我建议你把put Thread.sleep(5000)放在timer _worker_dowork函数本身。它不会影响你的应用程序,因为线程会休眠,gui仍然会响应。

我认为,通过我所做的事情,我已经调用了进度条,所以我不需要ReportProgress:

_worker.ReportProgress((int)(((decimal)i / (decimal)20) * 100));

更改为:

if (progressBar1.InvokeRequired)
    progressBar1.Invoke((Action)(() => progressBar1.Value = (int)(((decimal)i / (decimal)20) * 100)));
else
    progressBar1.Value = (int)(((decimal)i / (decimal)20) * 100);

这意味着,我不必挂起BackgroundWorker,定时器在不同的线程上被调用,并将保持直到处理????