我有一个打开了许多(假设大约一千个) TcpClient对象的C#程序。我想要进入一种状态,它将等待任何这些连接发生的事情。
我不想为每个连接启动一个线程。
就像..。
while (keepRunning)
{
// Wait for any one connection to receive something.
TcpClient active = WaitAnyTcpClient(collectionOfOpenTcpClients);
// One selected connection has incomming traffic. Deal with it.
// (If other connections have traffic during this function, the OS
// will have to buffer the data until the loop goes round again.)
DealWithConnection(active);
}
其他信息:
TcpClient对象来自TcpListener。
目标环境将是MS .NET或Mono-on-Linux。
当连接打开时,该协议需要长时间的空闲。
发布于 2011-04-04 17:14:46
您尝试做的事情在Microsoft术语中称为异步模式。总体思路是将所有I/O阻塞操作更改为非阻塞。如果这样做了,应用程序通常需要与机器上的CPU核心一样多的系统线程。
看看.Net 4中的任务并行库:http://msdn.microsoft.com/en-us/library/dd460717%28VS.100%29.aspx
它是一个相当成熟的包装器,超越了传统的Begin/Callback/Context .Net范例。
更新:
考虑一下在从连接中读取数据后将如何处理数据。在现实生活中,您可能必须回复客户端或将数据保存到文件中。在这种情况下,您将需要一些C#基础设施来包含/管理您的逻辑,并且仍然停留在单个线程中。TPL免费提供给您。它唯一的缺点是它是在Mono 4中引入的,所以它可能还没有出现在.Net中。
另一件需要考虑的事情是连接的生命周期。您的连接多长时间打开/关闭一次,以及它们的生存时间有多长?这一点很重要,因为接受和断开TCP连接需要与客户端进行数据包交换(本质上是异步的,而且恶意客户端可能根本不会返回确认(-nowledged)数据包)。如果您认为这方面对您的应用程序很重要,那么您可能想要研究一下如何在.Net中正确处理这一点。在WinAPI中,对应的函数是AcceptEx和DisconnectEx。它们可能被包装在带有Begin/End方法的.Net中-在这种情况下,您就可以使用了。否则,您可能不得不在这些WinAPI调用上创建一个包装器。
https://stackoverflow.com/questions/5541811
复制