我的问题是,什么时候我应该,什么时候我不应该线程?
谁能给出一些一般的规则?
假设我有一个mainForm,我想在另一个线程中做一些业务。
我应该:- 创建一个新线程,如
- 声明一个委托,如
myDelegate.BeginInvoke(IsyncCallback)
(委托,不是控制,是:) - 创建
System.ComponentModel.BackgroundWorker()
Thread t = new Thread(new ThreadStart(ThreadProc));
的最佳性能?
示例场景:
- 从数据库中获取数据到控制,或严重的后台计算
- 可能是多线程,如果是像ATM这样的东西
- 一个你想要永远活下去的线程
请给我深刻的解释,而不是像"I guess"那样:)
你可能会问,新线程在做什么?这就是为什么我想要一些通用规则,它可能会有所不同。谢谢!
为最佳性能!
您应该从这些选项中进行选择,不是因为性能,而是因为它们提供的功能。
在这些选项中,BackgroundWorker
拥有最好的设施。
- 直接支持协作线程取消(唯一正确的类型)
- 它支持将更新推送到UI的接口
- 支持自动线程池。
这可以提高性能,因为系统不需要生成新的线程来满足您的请求,而是从现有的线程池中进行分配。
其他两个选项没有那么好的内置设施。在一个实现得很好的UI应用程序中,你必须自己构建它们,我不认为大多数人在没有大量工作的情况下会比BackgroundWorker
的实现做得更好。
你可能还想考虑。net 4.0及以上版本的任务并行库。它支持取消,更直接地集成到语言中,链接和依赖任务,以及其他有趣的特性。
[From comments:]我不关心-我只是想知道区别
线程是所有这些中最原始的构造。它在。net中提供了基本的线程支持。这是低级别的,应该避免使用,除非你没有更好的选择来满足你的需求。
委托。BeginInvoke是一个允许某人创建基于任务的线程库的钩子。有人可以将一个委托传递给那个库,或者那个库可以存储一个委托列表。从这些,它将调用BeginInvoke
在他们上产生线程。这些线程是从线程池中分配的。这是一个构建块,尽管在比Thread
更高的级别。你可能想使用更高级的设施。
BackgroundWorker是这些选项中最用户友好的。它对于UI (GUI或命令行)应用程序最有用,在这些应用程序中,您希望向用户提供有关特定后台任务状态的反馈。它还支持协作取消。这两种情况都很常见。
还有其他你没有提到的工具,比如直接使用线程池,或者任务并行库。它们还适用于其他任务,值得一看和考虑。
请给我深刻的解释,而不是像"I guess"那样:)
人们无法猜测他们无法运行的代码的性能。作为线程性能的一般规则,您可能不应该关心它,除非您正在编写一个极其处理器密集型的算法。然后,你通常应该关注你的算法,并使其完全可并行,而不是担心底层细节,如线程设施的性能。
你一定要分析你的代码,以确定代码库中的瓶颈,并看看你是否可以改进它们。你不能用一组编程规则来抢占分析。
从数据库中获取数据以控制-否则将进行严重的后台计算!
DB读取是IO绑定,而不是CPU绑定。在这种情况下,您正在执行线程以等待后台任务,而不是执行线程以最大化CPU使用率。在这种情况下不用担心头部性能