C# 后台工作人员暂停

C# 后台工作人员暂停,c#,visual-studio-2010,timer,thread-safety,backgroundworker,C#,Visual Studio 2010,Timer,Thread Safety,Backgroundworker,我有一个背景工人\u工人 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(); } 当它到达行\u timer

我有一个
背景工人
\u工人

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();
}
当它到达行
\u timer.Start()
时,它认为它已完成,因此触发
RunWorkerCompleted事件

我不希望在达到
\u timer.Interval
时间并且触发
\u timer appead 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();
}
void\u timer\u已过(对象发送器,System.Timers.ElapsedEventArgs e)
{
对于(int i=1;i<20;i++)
{
如果(listBox1.InvokeRequired)
调用((操作)(()=>listBox1.Items.Add(“做事情线程”));
其他的
列表框1.Items.Add(“完成任务”);
_工人报告进度((整数)((十进制)i/(十进制)20)*100);
睡眠(1000);
}
_timer.Stop();
}
因为我需要
BackgroundWorker
报告一些进度


我该怎么做呢。我需要它在不同的
线程上运行

您的_timer\u expased事件在不同的线程上。一旦控制流通过_worker _DoWork函数,计时器实例就会过期。timer对象变量的作用域仅限于函数,因此它不会以这种方式工作


我建议你把Thread.sleep(5000)放在timer\u worker\u dowork函数中。它不会影响您的应用程序,因为线程将处于休眠状态,gui仍会响应。

我认为,仅仅通过玩弄我所做的事情,我已经调用了进度条,因此我不需要报告进度:

_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,计时器在另一个线程上被调用,并将一直保持到处理完毕???

以便总结讨论和解决方案

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

如果SynchronizingObject属性为null,则运行的事件为空 在线程池线程上引发。如果正在处理经过的事件 持续时间超过间隔,事件可能会在另一个服务器上再次引发 线程池线程。在这种情况下,事件处理程序应该是 可重入的

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


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

您知道已经有线程计时器了吗?我不是。。。。你能给我指一下MSDN页面吗?是的,当然-另外,System.Timers.Timer可以按照MSDN-如果SynchronizingObject属性为null,则在线程池线程上引发已用事件。如果已用事件的处理持续时间超过间隔,则可能会在另一个线程池线程上再次引发该事件。在这种情况下,事件处理程序应该是可重入的。“哦,如何使某些东西可重入?不过你在混合线程。不管怎样,计时器都会在事件中提高经过的时间。只需执行调用,根本不需要后台工作人员。UI响应会受到影响吗?我想我是在走系统、线程、计时器的路线!不,是螺纹的。UI只会在你在那个线程上做一些事情时才会受到影响。我完全摆脱了后台工作人员,一切都很好!