线程问题 - 我应该何时以及何时不应该进行线程处理以获得最佳性能?

时间:2011-11-22 21:57:10

标签: c# multithreading

我的问题是,我什么时候应该什么时候不应该穿线?

任何人都可以提供一些一般规则吗?

假设我有一个mainForm,我想在另一个线程中做一些事情。

我应该:

  • 创建一个新主题,例如Thread t = new Thread(new ThreadStart(ThreadProc));
  • 声明一个委托,例如myDelegate.BeginInvoke(IsyncCallback)(委托,不是控制,是:)
  • 创建System.ComponentModel.BackgroundWorker()

获得最佳表现?

示例场景:

  • 从数据库中获取数据以进行控制或严肃的背景计算
  • 如果它像ATM一样,可能是多线程
  • 你想永远活着的主题

请给我深刻的解释,而不是'我猜':)

你可能会问,新线程正在做什么业务?这就是我想要一些一般规则的原因,它可能会有所不同。

谢谢!

1 个答案:

答案 0 :(得分:3)

  

为了获得最佳表现!

您应该从这些选项中选择不是因为性能,而是因为它们提供的设施。

在这些选项中,BackgroundWorker拥有最佳设施。

  • 它直接支持协作线程取消(the only correct type
  • 它支持用于推送UI更新的界面
  • 支持自动线程池 这可以提高性能,因为系统不必生成新线程来满足您的请求,而是从现有的线程池中分配。

另外两个选项并没有内置的设备。在一个很好实现的UI应用程序中,你必须自己构建它们,而且我认为大多数人都不会做得好得多。 BackgroundWorker的实现没有太多工作。

您可能还想考虑the Task Parallel Library in .Net 4.0 and above。它支持取消,更直接地集成到语言,链接和依赖任务以及其他有趣的功能。

  

[来自评论:]我不担心 - 我只是想知道差异

Thread是所有这些中的原始构造。它在.Net中提供基本的线程支持。它是低级别的,应该避免,除非你没有更好的选择,以满足你的需求。

Delegate.BeginInvoke是允许某人创建基于任务的线程库的钩子。有人可以将该库传递给委托,或者该库可以存储委托列表。从这些开始,它会调用BeginInvoke来生成线程。这些线程是从线程池分配的。这是一个构建块,但比Thread更高。您可能想要使用更高级别的设施。

BackgroundWorker是这些选项中最友好的用户。对于希望向用户提供有关特定后台任务状态的反馈的UI(GUI或命令行)应用程序,它非常有用。它还支持合作取消。这两件事都非常普遍。

您还没有提及其他设施,例如using thread pools directly或任务并行库。这些适用于其他任务,值得一看和考虑。

  

请给我深刻的解释,而不是'我猜':)

人们无法猜测他们无法运行的代码。作为线程性能的一般规则,除非您编写极其处理器密集型算法,否则您可能不应该关注它。然后你应该关注你的算法,并在担心线程设施的性能之类的低级细节之前使其成为fully parallelizable

您绝对应该对代码进行分析,以确定代码库中的瓶颈,看看是否可以改进它们。您不能使用一组编程规则来抢占分析。

  

从数据库中获取数据以进行控制 - 或者进行背景计算!

数据库提取是IO绑定,而不是CPU绑定。在这种情况下,您正在线程等待后台任务,而不是线程以最大化CPU使用率。在这种情况下,不要担心这种情况。