我有一台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上运行。
发布于 2013-01-11 00:12:08
因此,总结一下讨论和解决方案。
除非你提供一个同步对象,否则System.Timers.Timer会自动为你线程计时器事件,如MSDN中所述:
如果SynchronizingObject属性为null,则在ThreadPool线程上引发Elapsed事件。如果对已用事件的处理持续时间超过时间间隔,则可能会在另一个ThreadPool线程上再次引发该事件。在这种情况下,事件处理程序应该是可重入的。
这意味着后台工作者变成了多余的人。您可以简单地让您的计时器事件代码按原样运行(因为它使用invoke与UI交互)。
这确实意味着,如果这些事件花费很长时间,它们可以并发运行。但是,您当然可以在事件回调中停止和启动计时器。
发布于 2013-01-10 21:28:04
您的_timer_Elapsed事件位于另一个线程上。一旦控制流通过_worker_DoWork函数,timer的实例就会过期。timer对象变量的作用域仅限于函数,因此它不会以这种方式工作。
我建议您将Thread.sleep(5000)放入计时器_worker_dowork函数本身。它不会影响您的应用程序,因为线程将休眠,而gui仍将响应。
发布于 2013-01-10 21:33:05
我认为,通过玩弄我所做的事情,我已经调用了进度条,所以我不需要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,计时器是在不同的线程上调用的,并将一直保持到释放?
https://stackoverflow.com/questions/14258872
复制相似问题