fre*_*ith 163 .net multithreading backgroundworker winforms
我有一个关于我应该在Windows窗体应用程序上使用的后台线程实现的选择的风格问题.目前我BackgroundWorker
在一个具有无限(while(true))
循环的表单上.在这个循环中,我WaitHandle.WaitAny
用来保持线程打盹直到感兴趣的事情发生.我等待的一个事件句柄是一个" StopThread
"事件,这样我就可以摆脱循环.来自我被覆盖的事件会发出此事件的信号Form.Dispose()
.
我读到的某个地方BackgroundWorker
真的是用于那些你不想将UI绑定到并且具有有限结束的操作 - 比如下载文件或处理一系列项目.在这种情况下,"结束"是未知的,并且仅在窗口关闭时.因此,使用后台线程而不是BackgroundWorker
为此目的更合适吗?
Mat*_*vis 361
我的一些想法......
Par*_*ice 87
根据我对您的问题的理解,您使用的BackgroundWorker
是标准线程.
为什么原因BackgroundWorker
建议的事情,你不想占用UI线程是因为它做赢形式的发展时,暴露了一些不错的活动.
事件喜欢RunWorkerCompleted
在线程完成它需要做的事情时发出信号,以及ProgressChanged
在线程进度上更新GUI 的事件.
因此,如果您没有使用这些,我认为使用标准线程不会对您需要做什么造成任何伤害.
pie*_*rs7 12
几乎是马特戴维斯所说的,还有以下几点:
对我来说,主要区别BackgroundWorker
在于通过自动编组已完成的事件SynchronizationContext
.在UI上下文中,这意味着已完成的事件在UI线程上触发,因此可用于更新UI.如果您BackgroundWorker
在UI上下文中使用,这是一个主要的区别.
通过它执行的任务ThreadPool
不能轻易取消(包括ThreadPool
.QueueUserWorkItem
和委托执行异步).因此,虽然它避免了线程旋转的开销,但是如果你需要取消使用BackgroundWorker
或者(更可能在UI之外)启动一个线程并保持对它的引用,这样你就可以调用Abort()
.
Mat*_*att 11
你也在为后台工作者的生命周期绑定一个线程池线程,这可能会引起关注,因为它们只有有限数量.我会说,如果你只是为你的应用程序创建一次线程(而不是使用后台工作程序的任何功能),那么使用一个线程,而不是一个backgroundworker/threadpool线程.
您知道,无论您使用的是Windows窗体,WPF还是其他任何技术,有时使用BackgroundWorker都会更容易.关于这些人的整洁部分是你得到线程,而不必过多担心线程执行的位置,这对于简单的任务非常有用.
在使用BackgroundWorker
考虑之前,如果你想取消一个线程(关闭应用程序,用户取消),那么你需要决定你的线程是否应检查取消或是否应该强制执行本身.
BackgroundWorker.CancelAsync()
将设置CancellationPending
为true
但不会再执行任何操作,然后线程负责不断检查这一点,请记住,您可能会在此方法中最终遇到竞争条件,您的用户已取消,但线程在测试之前已完成CancellationPending
.
Thread.Abort()
另一方面,在强制取消该线程的线程执行中抛出一个异常,如果在执行过程中突然引发了这个异常,你必须小心可能存在危险.
无论任务是什么,线程都需要非常仔细地考虑,以便进一步阅读:
我在知道.NET之前就知道如何使用线程,因此当我开始使用BackgroundWorkers时花了一些时间来适应它。马特·戴维斯(Matt Davis)非常出色地总结了它们之间的区别,但是我要补充一点,要准确地理解代码的作用更加困难,这会使调试变得更加困难。考虑到创建和关闭线程(IMO)要比考虑将工作分配给线程池要容易得多。
我仍然无法评论其他人的帖子,因此请原谅我一时的me脚,使用答案来回答码头问题
不要使用Thread.Abort(); 而是通知一个事件,并设计您的线程使其在收到信号后优雅地结束。Thread.Abort()在线程执行过程中的任意点引发ThreadAbortException,它可以执行各种不愉快的事情,例如孤立监视器,损坏的共享状态等。 http://msdn.microsoft.com/zh-CN/library/system.threading.thread.abort.aspx
我想指出BackgroundWorker 类的一种尚未提及的行为。您可以通过设置 Thread.IsBackground 属性使普通线程在后台运行。
后台线程与前台线程相同,只是后台线程不会阻止进程终止。[ 1 ]
您可以通过在表单窗口的构造函数中调用以下方法来测试此行为。
void TestBackgroundThread()
{
var thread = new Thread((ThreadStart)delegate()
{
long count = 0;
while (true)
{
count++;
Debug.WriteLine("Thread loop count: " + count);
}
});
// Choose one option:
thread.IsBackground = true; // <--- This will make the thread run in background
thread.IsBackground = false; // <--- This will delay program termination
thread.Start();
}
Run Code Online (Sandbox Code Playgroud)
当 IsBackground 属性设置为 true 并且您关闭窗口时,您的应用程序将正常终止。
但是,当 IsBackground 属性设置为 false(默认情况下)并且关闭窗口时,只有窗口会消失,但进程仍会继续运行。
BackgroundWorker 类利用在后台运行的线程。
归档时间: |
|
查看次数: |
112823 次 |
最近记录: |