我认为C#是一种事件驱动的编程语言。
对我来说,这种事情看起来相当混乱和低效:
tcpListener.Start();
while (true)
{
TcpClient client = this.tcpListener.AcceptTcpClient();
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientCommunication));
clientThread.Start(client);
}
在等待新消息到达时,我也必须做同样的事情。显然,这些函数都包含在一个线程中。
有没有更好的方法来做这个不涉及无限循环和浪费的CPU周期?活动?通知?什么东西?如果没有,那么做一个Thread.Sleep是不好的做法,所以它不像往常一样处理?
答案 0 :(得分:1)
您发布的方法绝对没有错。像你提到的那样,也没有浪费的CPU周期。 TcpClient.AcceptTcpClient()
阻塞线程,直到客户端连接到它,这意味着它不会占用任何CPU周期。因此,循环实际循环的唯一时间是客户端连接。
当然,如果你想要一种方法退出循环并停止监听连接,你可能想要使用while(true)以外的东西,但这是另一个主题。简而言之,这是接受连接的好方法,我认为没有任何目的在这里任何地方Thread.Sleep
。
答案 1 :(得分:1)
实际上有三种方法可以处理套接字的IO操作。第一个是像你一样使用阻塞功能。它们通常用于处理客户端套接字,因为客户端在大多数情况下都期望并直接回答(因此可以使用阻塞读取)
对于任何其他套接字处理程序,我建议使用两种异步(非阻塞)模型之一。
第一个模型是最容易使用的模型。它由Begin / End方法名称和Begin方法的IAsyncResult
返回值识别。您将回调(函数指针)传递给Begin方法,该方法将在发生某些事件时调用。举个例子来看看BeginReceive。
第二个异步模型更像是windows IO模型(IO Completion Ports)。它也是.NET中的最新型号,应该为您提供最佳性能。由于SocketAsyncEventArgs
对象用于控制行为(比如操作完成时调用哪个方法)。您还需要知道可以直接完成操作,然后不会调用回调方法。详细了解RecieveAsync。