2009-02-16 64 views
1

如何改善以下情况的性能?提高C#代码的性能

我有一个应用程序接受跨网络的多个连接。该应用程序使用C#编写,并接受Socket连接。每五分钟,应用程序需要执行一个函数调用,以更新应用程序并将信息报告给套接字。截断代码如下

... 
{ 
    new Thread(Loop).Start(); 
} 

public Loop() 
{ 
    ... 
    while (true) 
    { 
     ... 
     string line = user.Read(); 
     ... 
    } 
    ... 
} 

上面的代码是当一个套接字连接到服务器什么是运行。 以下代码是每五分钟运行一次的代码。

... 
{ 
    new Thread(TryTick).Start(); 
} 

public void TryTick() 
{ 
    while(true) 
    { 
     Tick(); 
     Thread.Sleep(new TimeSpan(0, 5, 0)); 
    } 
} 

Tick()执行一些文件I/O操作以及解析一组非常有限的(小于1MB)XML数据。但是,这段代码会使我的处理器税收超过我原先想象的那样。一旦发生勾号,系统似乎会占用我双核心开发机器的整个Core,并且不会放过。这似乎是相当简单的事情,但也许我正在以简单的方式而不是快速的方式。

该系统意味着可以处理多达100个用户,更多的数据并且在加载过程中的响应时间小于1秒,因此性能是一个问题。

+0

我很抱歉。我手动重写了错误的代码。 – 2009-02-16 22:04:41

+0

“new Thread(Loop).Start();” - 如果这是你真的在做什么,那你为什么不使用线程池? – 2009-02-16 22:33:53

回答

1

您是否尝试过在发布模式下编译以查看速度有多大差异?

+0

这提高了性能。但是,如果连接1个用户并且有一小部分数据,它仍可以在大约15-20%的CPU上运行。虽然这可能足以满足要求。谢谢(你的)信息。 – 2009-02-16 22:24:39

-1

它看起来好像你对Tick()的调用是递归的。

我还建议您添加一些代码,允许您插入收集关于您所关心的功能的更好指标 - 例如,运行“Tick”功能需要多长时间。

它确实可以帮助诊断“哎呀!”像这些问题。

0

我想我会知道所有你在做蜱,为什么你在蜱这样做,但每当我在一个类似那种情况下,我使用EventWaitHandles

+0

这些似乎是C#实现的信号量。它们在这里如何适用? – 2009-02-16 22:26:33

0

要调用你的滴答递归。顺便说一句,你可以使用一个计时器,这正是你想要的那种情况。另外请注意,它可能会在某段时间后给出stackoverflow异常 - 不会在主要执行过程中报告它,因为它是一个线程(为所有未处理异常设置全局日志以获取相关信息)。

+0

查看更新的代码片段。这只是一个代码复制错误。 – 2009-02-16 22:13:00

0

你可以看看线程和文件读取操作,看看系统是否可以更好地分配负载。 IO非常昂贵,因此它在不同的线程上运行有时可以加快速度。为什么不尝试Parallel Extension for the .NET Framework来帮助解决这个问题呢,他们有一些很好的,简单的API函数来协助循环并行操作。

+0

看起来很有趣。如果我需要进一步提高性能,那么我绝对会研究它。 – 2009-02-16 22:34:29

5

在决定做什么之前,您确实需要剖析此代码。 。 。如果您无法访问分析器,请添加简单的工具来确定瓶颈的位置。从Tick()开始,验证它是问题的根源(而不是程序中的其他地方),然后根据需要重复Tick()的子部分。

你真的需要在这里进行配置和测量。 。 。假设你的性能问题可能导致你浪费大量时间。

0

我注意到在公共Loop()中while(true)循环中没有包含Thread.Sleep(0)。如果你还没有,你应该考虑添加它。线。睡眠(0)会告诉处理器使用分配给该线程的剩余时间用于可能需要它的其他线程/进程。如果没有这样的电话,你基本上无法理会处理器的时间。


    public Loop() 
    { 
     ... 
     while (true) 
     { 
      ... 
      string line = user.Read(); 
      ... 
      Thread.Sleep(0); 
     } 
     ... 
    } 

这可能不再是你的问题,我的建议可能并不适用于你的情况,但因为你还没有披露完整的源代码,很难确切地知道问题的根源。这只是一些需要思考的问题。

2

您正在使用一段时间(true)。大多数.NET套接字的东西应该实现某种形式的事件处理程序。您可以创建自定义的通用事件处理程序,这样侦听程序只会真正做其他事情,而不是侦听连接并转发到事件。插座接收处理程序的一些示例位于http://www.c-sharpcorner.com/Forums/ShowMessages.aspx?ThreadID=37717

当您将所有内容放在while循环中并使用Thread.Sleep()时,线程处于“睡眠”状态时仍在使用处理器。

还要确保在完成使用线程时您正在执行Thread.Join()。否则,最终会有许多线程等待工作,除了占用多余的内存和处理器之外别无他法。

通常情况下,如果你的代码中有一个while(true)循环,而Thread.Sleep()则应该问自己,如果你做错了什么。在大多数情况下,你是,而且重构的最佳点是找出不使用资源来处理请求的方式。

0

不是打开一个线程,并把它睡觉我会建议你使用一个计时器,并使用Tick事件的,这是他们是为制作。

另外你应该写什么剔,所以我们可以帮助你更好