代码之家  ›  专栏  ›  技术社区  ›  GilliVilla

C#现实世界应用程序中的线程

  •  5
  • GilliVilla  · 技术社区  · 14 年前

    毫无疑问,学习线程是一件非常有趣的事情,有一些非常好的资源可以做到这一点。但是,我的问题是,在实际应用程序中,线程是作为设计或开发的一部分显式应用的。

    我曾在C中开发过一些广泛使用且架构良好的.NET应用程序,但没有发现显式使用的痕迹。由于CLR对其进行管理,是否真的没有必要,或者有什么具体原因?

    此外,任何在广泛使用的.NET应用程序中编码的线程示例。在Codelplex或google中,代码也是受欢迎的。

    10 回复  |  直到 13 年前
        1
  •  3
  •   Jon Skeet    14 年前

    这完全取决于应用程序。

    客户 需要做任何重要工作(或执行其他可能长时间运行的任务,如进行web服务调用)的应用程序,我希望使用后台线程。这可以通过 BackgroundWorker ,显式使用线程池,显式使用并行扩展,或显式创建新线程。

    根据我的经验,Web服务和Web应用程序创建自己的线程的可能性较小。您更有可能有效地将每个请求视为有一个单独的线程(即使ASP.NET在内部移动它),并同步执行所有操作。当然有 web应用程序要么异步执行,要么出于其他原因启动线程——但我想说,这种情况出现的频率比客户端应用程序要低。

        2
  •  5
  •   SLaks    14 年前

    如果在UI线程上执行该操作,整个GUI将冻结,直到完成为止(因为它不会运行消息循环)
    通过在后台线程上执行它,UI将保持响应。

    这个 BackgroundWorker

        3
  •  4
  •   Reed Copsey    14 年前

    在实际应用程序中,线程是作为设计或开发的一部分显式应用的。

    为了充分利用现代的多核系统,线程必须从一开始就成为设计的一部分。虽然很容易(尤其是在.NET4中)找到要执行的代码的一小部分,以获得真正的可伸缩性,但您需要设计算法来处理线程化,最好是在代码的“高级别”。在设计阶段越早完成,就越容易在应用程序中正确构建线程。

    肯定有必要。线程不是免费的-它必须由开发人员添加进来。这一点不经常出现的主要原因,尤其是在开源代码中,实际上更多的是一个困难的问题。即使使用.NET4,正确地设计算法以一种可伸缩的、安全的方式执行线程也是困难的。

        4
  •  2
  •   Prashant at Corensic    14 年前

    我不太喜欢Parallel.For、Parallel.Foreach和Parallel.Invoke(regions),因为我认为它们应该是纯语言扩展,而不是类库。很明显,我理解为什么我们有这个中间步骤,但是C#获得并发性的语言改进是不可避免的,同样不可避免的是我们必须返回并更改代码以利用它:-)

    总的来说,如果你正在考虑在.NET中构建并发应用程序,那么你应该研究一下并行扩展。我还认为,考虑到这是微软的一项相当新生的工作,你应该非常清楚什么适合你,什么不适合你,独立于你认为你自己的技能水平与并发性。微软肯定在听,但我认为还没有那么多人在使用并行扩展。昨天我在vsliveredmond观看了一个关于这个话题的会议,并继续对这个团队的工作印象深刻。

    Corensic 我们正在构建工具来检测并发应用程序中的bug。

        5
  •  1
  •   Adam Houldsworth    14 年前

    我见过的大多数线程的实际用法都是为了避免阻塞——UI、网络、数据库调用等。

    BeginXXX EndXXX delegate.BeginInvoke 电话, Control.Invoke 电话。

    我认为可以公平地说,您发现许多股票和交易应用程序(数据表示)基本上不需要大量的并行,也不总是能够被设计为适合它。我看到的例子都是非常具体的问题。这可能是因为您没有看到任何值得注意的实现。

        6
  •  1
  •   RobS    14 年前

    是否使用显式线程实现的问题通常是一个设计考虑因素,其他人在这里已经提到过。尝试将并发作为事后的想法来实现通常需要进行大量彻底的修改。

    根据我的经验,实现线程设计最常见的地方是在Windows服务(后台应用程序)和有用例场景的应用程序上,在这些场景中,大量的工作可以很容易地分解成更小的工作包(并交给线程异步完成)。

    例如,您可以查看 Microsoft Robotics Studio (据我所知 free version Concurrency and Coordination Runtime ,微软的 Channel 9

    正如其他人提到的,并行扩展团队( blog is here MSDN Code site .

        7
  •  0
  •   Jimmy Hoffa    14 年前

    线程应用于各种场景,任何基于网络的东西都依赖于线程,无论是显式(sockets)还是隐式(web服务)。线程保持UI的响应性。以及具有多个并行运行的windows服务,它们在处理需要处理的队列中的数据时执行相同的操作。

    这些只是我见过的最常见的。

        8
  •  0
  •   quentin-starin    14 年前

    事实上,就在此时此刻,我正在检查一个应用程序,它将一个200MB的文件上传到200个不同的FTP位置。我们使用 SmartThreadPool 并且并行运行大约50次上传,这允许整个批在不到一小时内完成(与所有上传连续进行超过50个小时相反-因此在我们的使用中,我们发现几乎直线的时间改进)。

        9
  •  0
  •   Sruly    14 年前

    但有时需要自己来穿线。例如,在我构建的一个web应用中,我有一个邮件队列,我从应用中添加到其中,并且有一个后台线程发送电子邮件。如果线程注意到队列的填充速度快于它发送的速度,那么它将创建另一个线程,如果它随后看到该线程处于空闲状态,它将杀死它。我想这可以通过更高层次的抽象来完成,但我是手动完成的。

        10
  •  0
  •   Mark Mullin    14 年前

    我无法抗拒边缘的情况-在一些应用程序中,要么必须实现高度的操作确定性,要么必须容忍高度的操作不确定性,然后线程和进程从最初的架构设计一直考虑到最终交付

    案例1-对于必须实现极高操作可靠性的系统,在投票架构中可以使用三个使用三种不同机制的完全独立的子系统-在每个投票人中产生3个线程/进程,等待它们结束/死亡/被杀死,如果他们说的都是同一件事-例如-复杂的航空电子系统

    案例2-对于必须处理高度不确定性的系统-做同样的事情,但一旦有什么东西回到你身边,就杀掉掉队的人,并给出你得到的最佳答案-例如-复杂的盘中交易算法试图摧毁使用它们的业务:-)