计时器与重复后台辅助角色

本文关键字:角色 后台 计时器 | 更新日期: 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 更容易处理。 与其他选择相比。

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

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

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

BackgroundWorker对于你想做的事情毫无意义。 您要做的只是在执行某些代码之前等待 500 毫秒,因此只需使用 System.Windows.Forms.Timer .