计时器与重复的背景工作者

时间:2013-10-01 16:05:33

标签: c# multithreading winforms wcf timer

我正在开发一个Windows窗体应用程序,它在指定的时间间隔后调用WCF服务,并根据从服务接收的数据显示输出。我有一个计划为此目的使用计时器,在500毫秒后调用该WCF服务方法。但我的一些同事告诉我使用后台工作人员,然后在Work_Completed事件重新运行工人。我想知道这两者有什么区别? timer还会创建后台线程吗?哪一个最适合长期运行的任务?

4 个答案:

答案 0 :(得分:6)

From MSDN website: -

  

BackgroundWorker在ThreadPool上创建一个线程(通过异步)   委托调用)。 BCL计时器使用ThreadPool线程   提高事件,或者在某些情况下会提高勾选/经过/等   UI线程上的事件(在WinForms计时器或   提供了ISynchronizeInvoke的Timers.Timer)。

     

BackgroundWorker为后台线程提供了最佳API   UI环境。它允许一种方法在后台运行   线程(通过DoWork事件)并提供一种简单的通知方式   UI线程上的进度和完成(ProgressChanged和   RunWorkerCompleted事件),无需担心任何问题   跨线程调用。

     

WinForms计时器在UI线程上执行,可以安全地触摸任何一个   来自其已过去事件的UI元素。但是,您无法保证   按照确切的时间间隔执行,它完全取决于正在发生的事情   UI线程。让我重复一件重要的事情:没有   这个选项的后台线程!

     

Threading.Timer是一种“丑陋的API”计时器。 Timers.Timer简单   将Threading.Timer包装到更好的API中并提供了一种方法   自动调用UI线程上的已用事件(通过   SynchronizingObject属性)。如果设置SynchronizingObject   属性,没有代码在后台线程上执行,它立即获得   编组到UI线程。

     

通常,在UI中,BackgroundWorker更容易处理   与其他选择相比。

答案 1 :(得分:5)

在资源消耗方面,Timer几乎肯定更合适。 BackgroundWorker将为该任务创建一个新线程。创建新线程是一项相当昂贵的操作。虽然有许多不同的计时器实现,并且它们的实现会有所不同,但它们通常依赖于定期触发事件的OS工具,这将比启动新的专用线程更好。

Timer对象中的大多数关键差异都是他们“准备好”时所做的事情。有些人创建了一个新的线程池线程;有些专用线程由计时器的所有实例共享以运行处理程序,有些将代码编组到UI线程(或其他一些同步上下文),而后者则是您可能想要的。如果您使用在您正在使用的特定UI框架中提供的计时器,那么您将看到的行为。

答案 2 :(得分:4)

根据我的经验,主要好处Background WorkerProgressChangedRunWorkerCompleted事件将在工作者实例化的同一线程上执行。因此,如果您在UI线程上启动后台工作程序,则RunWorkerCompleted事件也将在UI线程上触发。这使得如果您想在后台工作完成时更新UI组件,则不必担心进行非法的跨线程调用。

答案 3 :(得分:3)

标准System.Windows.Forms.Timer应该没问题。它在UI线程上调用它的回调,这意味着当你在回调内处理时,它可能会冻结你的UI响应。但是如果你在回调中做了很多工作或者你阻止了线程,这只是一个问题。

为了避免阻塞线程,只需执行异步WCF调用。

BackgroundWorker对你想做什么毫无意义。你要做的就是在执行一些代码之前等待500ms,所以只需使用System.Windows.Forms.Timer