![](/img/trans.png)
[英]Performance impact of creating large number of threads in C# Application
[英]Best pattern for creating large number of C# threads
我们正在实现一个C#应用程序,该应用程序需要与旧系统建立大量的套接字连接。 我们(可能)将使用第三方组件对终端仿真和数据抓取进行繁重的工作。 今天,我们的核心功能正在运行,现在我们需要对其进行扩展。
在高峰时期,可能需要打开数千个并发连接-aka线程(甚至每年数以万计的线程)。 这些连接主要在几分钟(或几小时)内处于空闲状态(除了周期性的握手,没有流量),直到旧系统“触发我们关注的事件”,然后从该事件中抓取一些数据,执行一些工作流程,然后等待下一个事件。 池化没有任何价值(据我们所知),因为很少需要重用线程。
我们正在寻找任何有效的模式或工具来帮助有效地使用这么多线程。 在高端服务器硬件上运行不是问题,但如果可能的话,我们确实需要将应用程序限制为仅几个服务器。
在我们的测试中,创建一个新线程并初始化第三方控件似乎最初使用了大量CPU,但随后下降到接近零。 内存使用量大约为800Megs / 1000个线程
有没有比仅创建和启动所需线程数更好/更有效的方法?
PS-是的,我们知道创建这么多线程很不好,但是由于我们无法控制旧版应用程序,因此这似乎是我们唯一的选择。 一个套接字/连接中没有多个事件的选项。
感谢您的帮助或指点! 万斯
你这样说:
池化没有任何价值(据我们所知),因为很少需要重用线程。
但是然后你这样说:
有没有比仅创建和启动所需线程数更好/更有效的方法?
为什么会有差异? 您是否关心要创建的线程数? 线程池是处理大量大多数空闲连接的正确方法。 一些繁忙的线程可以轻松地处理许多空闲连接,并且所需资源更少。
使用套接字的异步BeginReceive和BeginSend。 这些将IO操作分派给操作系统并立即返回。
您将委托和一些状态传递给将在IO操作完成时调用的那些方法。
通常,一旦处理完IO,便立即再次调用BeginX。
Socket sock = GetSocket();
State state = new State() { Socket = sock, Buffer = new byte[1024], ThirdPartyControl = GetControl() };
sock.BeginReceive(state.Buffer, 0, state.Buffer.Length, 0, ProcessAsyncReceive, state);
void ProcessAsyncReceive(IAsyncResult iar)
{
State state = iar.AsyncState as State;
state.Socket.EndReceive(iar);
// Process the received data in state.Buffer here
state.ThirdPartyControl.ScrapeScreen(state.Buffer);
state.Socket.BeginReceive(state.buffer, 0, state.Buffer.Length, 0, ProcessAsyncReceive, iar.AsyncState);
}
public class State
{
public Socket Socket { get; set; }
public byte[] Buffer { get; set; }
public ThirdPartyControl { get; set; }
}
如果您接受传入的连接,则BeginSend的使用方式也与此类似,也可以使用BeginAccept的方式。
通过低吞吐量操作,异步通信可以轻松地同时处理数千个客户端。
我建议利用Socket.Select()方法,并在单个线程中集中处理多个套接字连接。
例如,您可以为与旧系统的每50个连接创建一个线程。 这些主线程只会继续调用Socket.Select()等待数据到达。 然后,这些主线程中的每个主线程都可以具有一个线程池,该线程池将具有数据的套接字传递到该线程池以进行实际处理。 一旦处理完成,线程可以被传递回主线程。
使用Microsoft的“协调和并发运行时”的多种模式使处理IO变得轻而易举。 它使我们能够在我们正在开发的搜寻器中每分钟抓取并处理超过6000个网页(可能会更高,但没有必要)。 绝对值得花时间将您的头转向CCR处事方式。 这里有一篇很棒的文章:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.