我有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
上运行。
答案 0 :(得分:1)
总结讨论和解决方案。
除非您提供同步对象,否则System.Timers.Timer将自动为您调度计时器事件,如MSDN中所述:
如果SynchronizingObject属性为null,则Elapsed事件为 在ThreadPool线程上引发。如果处理了Elapsed事件 持续时间超过Interval,事件可能会再次提升 ThreadPool线程。在这种情况下,事件处理程序应该是 折返。
这意味着后台工作者变成了超级流行音乐。你可以简单地让你的计时器事件代码运行(因为它使用invoke无论如何都与UI交互)。
这确实意味着如果这些事件需要很长时间,它们可以同时运行。但是,您当然可以在事件回调中停止并启动计时器。
答案 1 :(得分:0)
您的_timer_Elapsed事件位于其他线程上。一旦控制流通过_worker_DoWork函数,计时器的实例就会过期。您的计时器对象变量的范围仅限于该函数,因此它不会以这种方式工作。
我建议你把Thread.sleep(5000)放在timer _worker_dowork函数本身。它不会影响你的应用程序,因为线程会休眠,gui仍然会响应。
答案 2 :(得分: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,并且计时器是在另一个线程上调用的,并且会一直处理掉,直到被处理掉。