我正在开发一个到目前为止工作得很好的多线程服务器 - 一个用于客户端接受的独立线程,用于数据读取和处理的线程池。今天我添加了新的线程,用于做一些事情并每隔500毫秒向客户端发送消息(只有2-5条消息)。我注意到相当大的减速但我不确定为什么 - 它的单独线程并不是由于迭代和锁定集合,因为当我在SendMessage调用之前添加//时,它仍然像以前一样快。 SendMessage基本上迭代所有连接的客户端,并为每个客户端调用SendData方法,该方法将数据写入其网络流。 我错过了什么?我仍然认为那些是不同的线程,我希望它不是由于stream.write .. 提前谢谢!
答案 0 :(得分:0)
如果您可以尝试发布代码示例或摘要,您的消息发送实现将成为一个很好的候选者。
首先,纯粹的一般性建议。
现在是制作分析器的好时机。这种猜测很有诱惑力,通常是一种良好的心理练习,但大多数时候程序员对他们认为使他们的软件变慢的想法是错误的。例如,分析器会告诉您,您的程序是否在一个方法中花费了90%的执行时间。
第二,猜测猜测。
听起来你的消息命令会在计时器上运行。确保您没有重入问题 - 例如,如果您的sendmessage循环需要超过500毫秒才能完成(并且与创建新线程和多个不可预测的延迟网络调用一起,它可以做到这一点),并且您拥有整体在锁定中操作,然后计时器将继续产生脱离坐在该锁中的线程池线程,等待上一个操作完成 - 并且存在有限数量的可用线程池线程。要检查这是否是一个问题,您甚至不需要分析器,当延迟变得糟糕时暂停调试器并检查当前正在执行的线程列表。
如果是这种情况,请考虑做其他事情 - 比如让一个线程在无限循环中运行,使用等待句柄作为阻塞机制,并且计时器每隔500ms设置一次等待句柄。
但是如果你发布一些代码片段并运行一个分析器(Ants或DotTrace都很好),它会更容易帮助你。
答案 1 :(得分:0)
线程&像套接字服务器这样的线程池是旧的做事方式。它是非常不可扩展的(最好是你希望没有比核心更多的线程),并且充满了锁。
尝试将代码转换为异步代码。您只需要1个线程,并且只要输入到达或者可以发送新数据,您就会收到回调。生成的代码更快,并且没有这些瓶颈问题。
我知道这样的建议:不,不,重写你应该这样做的一切,并不是真的有用,因为它没有回答你问的确切问题。但如果你有时间,我仍然认为这是一个很好的建议。或者,对于您将要制作的下一个服务器,这是一个很好的建议; ^)