C# - 改进多线程应用程序设计

时间:2010-07-07 08:15:41

标签: c# design-patterns architecture multithreading

规范

  • C#分布式应用程序。
  • 客户端/服务器设计。
  • 客户端(Winforms),服务器(Windows服务),通过.Net Remoting进行通信。
  • 以下问题与应用程序的服务器端有关。
  • (编辑) 应用程序的服务器端 8 Core 和<的服务器上运行强> 12Gb Ram
  • (编辑) 此服务器的 CPU 总是达到 80%使用率其他服务在同一台服务器上运行。

方案

  • 我已经继承了一个大型遗留应用程序。
  • 它执行一系列任务,其中一些是独立的,但其他任务没有。
  • 此应用程序的当前设计涉及创建14个线程,每个线程运行1个任务或许多任务。
  • 问题在于我觉得这个设计元素对性能有影响。

代码示例 - 如何设计每个类/线程&amp;运行

public class ManageThreads
{
    private Thread doStuffThread = null;

    //Inside the constructor EVERY thread is instantiated and run.
    //(I am aware that this example only shows the use of 1 thread).
    public ManageThreads()
    {
       doStuffThread = new Thread(new ThreadStart(DoSomeStuff.Instance.Start));
       doStuffThread.Start();

       //Instantiate and run another thread.....
       //Instantiate and run another thread.....
       //Instantiate and run another thread.....etc.
    }

}

public class DoSomeStuff
{
    void Start()
    { 
        while(true)
        {
          //Repeatedly do some tasks.....

          Thread.Sleep(5000);
        }
     }   
 }

思想

  • 我想做的是保留现有代码,但要修改它运行的方式。
  • 我考虑过使用线程池来解决这个问题,但考虑到目前的体系结构,我不确定如何做到这一点。

问题

  • 这种当前设计是否会以明显的方式影响性能?
  • 我是否可以在不改变基础功能的情况下提高此应用程序的性能,但稍微改变设计?
  • 任何人都可以推荐任何东西/建议我正确的方法来改善这个吗?

非常感谢。

2 个答案:

答案 0 :(得分:4)

  

“我觉得这个设计元素会对性能产生影响。”

不要猜测,拿出一个分析器并测量发生了什么。收集一些关于应用程序中花费时间的经验统计数据,然后您可以查看夹点的位置。

如果创建线程所花费的时间是你最头痛的问题,那么转移到线程池可能是正确的答案,但如果没有一些取证分析你就不会知道。

从你发布的小片段来看,它看起来像14个线程相当长寿,在他们的一生中做了多件事,所以我怀疑这不是问题,但你的帖子里没有足够的信息对此作出最终决定。

答案 1 :(得分:0)

如果你的线程都在工作,并且你有比处理器更多的线程活动,那么你将花费时间上下文切换。

如果您拥有双核处理器,则不要期望通过4个以上的活动工作线程获得出色的性能。

因此,除非你有一个可以管理它的处理器,否则从14个开始工作的线程开始是一个坏主意。物理处理器架构和功能集对此有很大的影响。我的观点是线程池将有助于管理上下文切换,但是一次启动14个忙线程总是会扼杀性能......你可能会通过简单地按顺序排除线程来获得更快的性能。显然这是一个很大的陈述,所以可能不是特鲁斯,但你得到了要点。

因此,使用线程池和分析器来确定线程池可用的最佳线程数。

在大多数情况下,当人们使用线程池时,很多线程在大多数时间都没有做任何事情,或者线程正在休眠/阻塞,而某些慢速操作或外部依赖等待响应。

考虑使用异步模式,以便您可以获得有关线程进度的信息。

在双核处理器上,如果它们全部在100%的时间内工作,我会犹豫不决,超过3个线程