Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 定时器与重复后台工作器_C#_Multithreading_Winforms_Wcf_Timer - Fatal编程技术网

C# 定时器与重复后台工作器

C# 定时器与重复后台工作器,c#,multithreading,winforms,wcf,timer,C#,Multithreading,Winforms,Wcf,Timer,我正在开发一个Windows窗体应用程序,它在指定的时间间隔后调用WCF服务,并根据从服务接收到的数据显示输出。为此,我计划使用定时器,在500毫秒后调用WCF服务方法。但是我的一些同事告诉我使用后台工作程序,然后在工作完成时重新运行该工作程序。我想知道这两者的区别是什么?定时器是否也会创建一个后台线程?哪一个最适合长时间运行的任务?:- BackgroundWorker在线程池上创建线程(通过异步 委托调用)。BCL计时器使用线程池线程或 引发事件,或者在某些情况下会引发勾号/已过/等 UI线

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

:-

BackgroundWorker在线程池上创建线程(通过异步 委托调用)。BCL计时器使用线程池线程或 引发事件,或者在某些情况下会引发勾号/已过/等 UI线程上的事件(对于WinForms计时器或 计时器。提供ISynchronizeInvoke的计时器)

BackgroundWorker为中的后台线程提供了最佳API 用户界面环境。它允许在后台运行方法 线程(通过DoWork事件),并提供一种简单的通知方式 UI线程上的进度和完成情况(进度更改和 运行WorkerCompleted事件),而无需担心任何 跨线程调用

WinForms计时器在UI线程上执行,可以安全地触摸任何 UI元素从其已用事件中删除。但是,您不能保证 以精确的间隔执行,这完全取决于正在发生的事情 用户界面线程。让我重复一件重要的事情:没有 使用此选项的后台线程

计时器是一种“丑陋的API”计时器。定时器,定时器 将Threading.Timer包装到更好的API中,并提供了一种 在UI线程上自动调用已运行事件(通过 同步对象属性)。如果设置同步对象 属性,则不会在后台线程上执行任何代码,它会立即 封送到UI线程

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


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

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


BackgroundWorker
对你想做的事情毫无意义。您所要做的就是在执行某些代码之前等待500毫秒,因此就资源消耗而言,使用
系统.Windows.Forms.Timer
a
计时器几乎肯定更合适。
BackgroundWorker
将为该任务创建一个新线程。创建一个新线程是一个相当昂贵的操作。虽然有许多不同的计时器实现,它们的实现也会有所不同,但它们通常依赖于定期触发事件的操作系统工具,这比启动新的专用线程更可取


Timer
对象的主要区别在于它们在“准备就绪”时所做的事情。有的创建新的线程池线程;有些线程由计时器的所有实例共享以运行处理程序,有些线程将代码封送到UI线程(或其他同步上下文),您可能需要后者。如果您使用在所使用的特定UI框架中可用的计时器,您将看到它的行为。

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

什么计时器?有多个。有些人使用线程,有些人不使用。这意味着在更深层的系统级别上,标准计时器只是一个递归函数?@AishwaryaShiva否。你为什么这么说?@Servy正如我刚才在上面的回答中所读到的,计时器在UI线程上执行,所以据我所知,它应该是一个递归函数。因为它是UI线程(UI类)的一部分,执行时会冻结UI。我只是问你,我不确定。实际上我想知道在更深层次上什么是计时器?我看到了MSDN的解释,但它们只是用于开发目的。实际上,我想知道这一点是为了我的自我认识和研究。@AishwaryaShiva将事件调用封送到UI线程不需要递归;它只需要调用同步对象的适当方法就可以将事件处理程序添加到消息队列中。这并不是递归的。你可以使用(serveral)
Timer
类,它们也会在UI线程中打勾;你不需要BGW来获得这种行为。我认为默认情况下唯一在UI线程中打勾的是System.Windows.Forms.Timer。这里有一个很好的文章来比较定时器:<代码>系统。定时器。定时器< /C>可以被配置为在UI线程中触发,并且需要考虑每个UI范例特有的所有定时器。有表单计时器和WPF计时器(DispaterTimer),等等。