0

我有一个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.

4

3 回答 3

1

所以要总结讨论和解决方案。

System.Timers.Timer 将自动为您处理计时器事件,除非您提供同步对象,如 MSDN 中所述:

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

这意味着后台工作人员变得多余。您可以简单地让您的计时器事件代码按原样运行(因为它无论如何都使用调用与 UI 交互)。

这确实意味着如果这些事件需要很长时间,它们可以同时运行。但是,您当然可以在事件回调中停止和启动计时器。

于 2013-01-10T16:12:07.980 回答
0

我认为,只是通过玩弄我所做的,就是我已经调用了进度条,所以我不需要 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,并且计时器是在不同的线程上调用的,并且会一直保留到处理掉????

于 2013-01-10T13:33:05.387 回答
0

您的 _timer_Elapsed 事件在不同的线程上。只要控制流通过 _worker_DoWork 函数,计时器的实例就会过期。您的计时器对象变量的范围仅限于函数,因此它不会以这种方式工作。

我建议您将 Thread.sleep(5000) 放入计时器 _worker_dowork 函数本身。它不会影响您的应用程序,因为线程将休眠并且 gui 仍将响应。

于 2013-01-10T13:28:04.323 回答