计时器与重复后台辅助角色
本文关键字:角色 后台 计时器 | 更新日期: 2023-09-27 18:33:25
我正在开发一个 Windows 窗体应用程序,该应用程序在指定的时间间隔后调用 WCF 服务,并根据从该服务接收的数据显示输出。我计划为此目的使用计时器,在 500 毫秒后调用该 WCF 服务方法。但是我的一些同事告诉我使用后台工作线程,然后在Work_Completed
事件中重新运行工作线程。我想知道这两者之间有什么区别?计时器是否还会创建后台线程?哪一个最适合长时间运行的任务?
可以肯定,就资源消耗而言,Timer
更合适。 BackgroundWorker
将专门为该任务创建一个新线程。 创建新线程是一项相当昂贵的操作。 虽然有许多不同的计时器实现,并且它们的实现会有所不同,但它们通常依赖于将定期触发事件的操作系统工具,这比启动新的专用线程更可取。
Timer
对象中的大多数关键区别在于它们在"准备就绪"时执行的操作。 有些创建新的线程池线程;有些具有由计时器的所有实例共享的专用线程以运行处理程序,有些将代码封送到 UI 线程(或其他一些同步上下文(,您可能想要后者。 如果使用正在使用的特定 UI 框架中提供的计时器,则会看到该行为。
来自 MSDN 网站 :-
BackgroundWorker 在 ThreadPool 上创建一个线程(通过异步 委托调用(。BCL 计时器使用 ThreadPool 线程来 引发事件,或者在某些情况下会提高刻度/已用/等 UI 线程上的事件(在 WinForms 计时器或 Timers.Timer ,它有一个 ISynchronizeInvoke 提供给它(。
后台工作线程为后台线程提供了最佳 API 一个 UI 环境。它允许一种方法在后台运行 线程(通过 DoWork 事件(并提供一种简单的通知方式 UI 线程上的进度和完成情况(进度已更改和 运行工作线程处理事件(,而不必担心任何 跨线程调用。
WinForms 计时器在 UI 线程上执行,可以安全地触摸任何 来自其已用事件的 UI 元素。但是,您不能保证 以确切的时间间隔执行,这完全取决于正在发生的事情 UI 线程。让我重复一件重要的事情:没有 带有此选项的后台线程!
Threading.Timer 是一种"丑陋的 API"计时器。定时器.定时器简单 将 Threading.Timer 包装成更好的 API 中,并提供一种方法 自动调用 UI 线程上的已用事件(通过 同步对象属性(。如果设置了同步对象 属性,没有代码在后台线程上执行,它会立即得到 编送到 UI 线程。
一般来说,在UI内部,BackgroundWorker 更容易处理。 与其他选择相比。
根据我的经验,后台工作线程的主要好处是ProgressChanged
和RunWorkerCompleted
事件将在实例化工作线程的同一线程上执行。因此,如果在 UI 线程上启动后台辅助角色,则 RunWorkerCompleted 事件也将在 UI 线程上触发。这样,如果您想在后台工作完成时更新 UI 组件,则不必担心进行非法的跨线程调用。
标准System.Windows.Forms.Timer
应该没问题。 它在 UI 线程上调用其回调,这意味着当您在回调内处理时,它可能会冻结您的 UI 响应能力。 但这只是一个问题,如果你在回调中做了大量工作,或者如果你阻止了线程。
若要避免阻塞线程,只需执行异步 WCF 调用。
BackgroundWorker
对于你想做的事情毫无意义。 您要做的只是在执行某些代码之前等待 500 毫秒,因此只需使用 System.Windows.Forms.Timer
.