简体   繁体   English

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

[英]C# - Improving a Multi-Threaded Application Design

Specification 规格

  • C# Distributed Application. C#分布式应用程序。
  • Client/Server design. 客户端/服务器设计。
  • Client (Winforms), Server (Windows Service), Communication via .Net Remoting. 客户端(Winforms),服务器(Windows服务),通过.Net Remoting的通信。
  • The below question relates to the Server-Side of the application. 以下问题与应用程序的服务器端有关。
  • (EDIT) The Server-side of the application runs on a server with 8 Cores and 12Gb Ram (编辑)的服务器上的应用程序运行的服务器端8个核心12GB拉姆
  • (EDIT) The CPU of this server is always hitting around 80% Usage due to lots of other services being run on this same server. (编辑)由于同一台服务器上正在运行许多其他服务,因此该服务器的CPU 使用率始终达到80%左右。

Scenario 脚本

  • I've inheritted a large legacy application. 我继承了一个大型的遗留应用程序。
  • It carries out a bunch of tasks, some of them independently, but others not. 它执行一堆任务,其中一些任务是独立的,而其他任务则不是。
  • The current design for this application involves the creation of 14 threads, each running either 1 task or a number of tasks. 该应用程序的当前设计涉及创建14个线程,每个线程运行1个任务或多个任务。
  • The problem is that I get the feeling this design element has an impact on performance . 问题是我感到这种设计元素会影响性能

Code Examples - How Each Class/Thread Is Designed & Run 代码示例-如何设计和运行每个类/线程

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);
        }
     }   
 }

Thoughts 思考

  • What I'd like to do is keep the existing code, but modify the way that it runs. 我想做的是保留现有代码,但修改其运行方式。
  • I've thought about the use of a Thread Pool to solve this problem, but given the current architecture I am unsure of how I would go about doing this. 我已经考虑过使用线程池来解决此问题,但是考虑到当前的体系结构,我不确定如何进行此操作。

Questions 问题

  • Would this current design affect performance in a noticeable way? 当前的设计是否会以明显的方式影响性能?
  • Is it possible for me to improve the performance of this application without altering the underlying functions, but changing the design slightly? 我是否有可能在不更改基础功能的情况下,但略微更改设计的情况下提高此应用程序的性能?
  • Can anyone recommend anything / advise me on the right way to go about improving this? 谁能推荐任何建议/以正确的方式建议我,以改善这一点?

Help greatly appreciated. 帮助极大的赞赏。

"I get the feeling this design element has an impact on performance." “我感到这种设计元素会影响性能。”

Don't guess, get a profiler out and measure what's going on. 不要猜测,将探查器拿出来并测量发生了什么。 Gather some empirical stats about where time is spent in the application and then you can take a view on where the pinch points are. 收集一些有关在应用程序中花费时间的经验统计信息,然后您可以查看收缩点在哪里。

If the time spent creating threads is your biggest headache then moving to a threadpool may be the right answer, but you won't know without some forensic analysis. 如果花费时间来创建线程是您最大的头疼,那么迁移到线程池可能是正确的答案,但是如果不进行一些取证分析,您将不会知道。

From the small snippet you've posted it looks like the 14 threads are reasonably long-lived, doing multiple things over their lifetime so I suspect that this is not the problem actually, but there isn't enough info in your post to make a definitive call on this. 从您发布的小片段中可以看出,这14个线程的寿命相当长,它们在整个生命周期中都会做很多事情,所以我怀疑这实际上不是问题所在,但是您的帖子中没有足够的信息来完成对此的明确呼吁。

if your threads are all doing work and you have more threads active than processors then you are going to be spending time context switching. 如果线程全部都在工作,并且活动线程多于处理器,那么您将花费时间进行上下文切换。

If you have a dual core processor dont expect to get great performance with more than 4 active working threads. 如果您有双核处理器,不要期望通过4个以上的活动工作线程获得出色的性能。

So starting off 14 threads that are all doing work is a bad idea unless you have a processor that can manage this. 因此,除非有一个可以管理该工作的处理器,否则从14个都在工作的线程开始是一个坏主意。 Physical processor architecture and feature set has a big impacrt on this. 物理处理器体系结构和功能集对此有很大的影响。 My point is that a threadpool will help manage the context switching but starting 14 busy threads at once is always gonna kill performance ... you will probably get faster performance from simply excuting the threads sequentially. 我的观点是,线程池将帮助管理上下文切换,但是一次启动14个繁忙线程总是会降低性能……通过顺序地执行线程操作,可能会获得更快的性能。 Obviously that is a big statement and so is probably not trus, but you get the gist. 显然,这是一个重要的声明,可能不是trus,但您可以理解要点。

Hence the use of a thread pool along with a profiler to figure out the optimum number of threads to make available to the thread pool. 因此,使用线程池和事件探查器来找出可用于线程池的最佳线程数。

In most situations when people are usign a thread pool a lot of the threads are doing nothing most of the time, or a thread is sleeping/blocking whilst some slow operation or external dependancy awaits a response. 在大多数情况下,当人们使用线程池时,很多线程在大多数时间都无所事事,或者线程正在休眠/阻塞,同时一些缓慢的操作或外部依赖关系正在等待响应。

consider using an asynch pattern so that you can get info about progress out of your threads. 考虑使用异步模式,以便您可以从线程中获取有关进度的信息。

On a dual core processor i would be hesitant abou tusing more than 3 threads if they are all working 100% of the time 在双核处理器上,如果它们都在100%的时间内都在工作,我会犹豫地增加3个以上的线程

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM