创建大量C#线程的最佳模式

时间:2009-08-28 02:15:14

标签: c# multithreading

我们正在实现一个C#应用程序,它需要与遗留系统建立大量套接字连接。我们将(可能)使用第三方组件来完成有关终端仿真和数据抓取的繁重工作。我们今天拥有核心功能,现在我们需要扩展它。

在高峰时段,这可能是需要打开的数千个并发连接 - 也就是线程(甚至每年数万次)。这些连接主要处于闲置状态(除定期握手之外没有流量)几分钟(或几小时),直到遗留系统“触发我们关心的事件”,然后我们从此事件中抓取一些数据,执行一些工作流程,然后等待下一个活动。池中没有任何价值(据我们所知),因为线程很少需要重复使用。

我们正在寻找有助于有效使用这么多线程的任何好的模式或工具。在高端服务器硬件上运行不是问题,但如果可能的话,我们确实需要将应用程序限制在几台服务器上。

在我们的测试中,创建一个新线程,并初始化第三方控件似乎最初使用了大量CPU,但随后降至接近零。内存使用似乎约为800Megs / 1000个线程

有没有比创建和启动所需线程数更好/更有效的方法?

PS - 是的,我们知道创建这么多线程是不好的,但由于我们无法控制遗留应用程序,这似乎是我们唯一的选择。多个事件没有选项可以遇到单个套接字/连接。

感谢您的帮助或指示! 面包车

5 个答案:

答案 0 :(得分:2)

你这样说:

  

汇集没有价值(到目前为止)   我们可以告诉)因为线程会   很少需要重复使用。

但是你这么说:

  

有什么更好/更多   高效而不仅仅是创造和   启动所需的线程数?

为什么会出现差异?您是否关心您创建的线程数量?线程池是处理大量空闲连接的正确方法。一些忙线程可以轻松处理许多空闲连接,并且所需资源更少。

答案 1 :(得分:1)

使用套接字的异步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。

低吞吐量操作异步通信可以轻松同时处理数千个客户端。

答案 2 :(得分:0)

我真的会关注MPI.NET。更多信息MPI。 MPI.NET也有一些并行缩减;所以这将很好地汇总结果。

答案 3 :(得分:0)

我建议使用Socket.Select()方法,并在单个线程中汇集多个套接字连接的处理。

例如,您可以为遗留系统的每50个连接创建一个线程。这些主线程将继续调用Socket.Select()等待数据到达。然后,这些主线程中的每一个都可以具有线程池,该线程池将具有数据的套接字传递给实际处理。处理完成后,线程可以传递回主线程。

答案 4 :(得分:0)

使用Microsoft的协调和并发运行时的许多模式使得IO易于处理和轻松处理。它允许我们在我们正在开发的爬虫中每分钟抓取和处理超过6000个网页(可能会更高,但没有必要)。绝对值得投入时间投入到CCR的做事方式。这里有一篇很棒的文章:

http://msdn.microsoft.com/en-us/magazine/cc163556.aspx