【问题标题】:Thread and TcpListener in C#C#中的线程和TcpListener
【发布时间】:2012-01-18 19:58:28
【问题描述】:

我需要编写一些使用TcpListener 的代码。使用TcpListener 的对象有3 种可能性:收听、停止收听、发送消息。这就是我的代码的样子:

public class someClass
{
    public bool listenerEnable {get; set; }

    public void StartListen()
    {
        .
        .
        .

        while (listenerEnable)
        {
            // Block until client connected
            TcpClient client = server.AcceptTcpClient();       

            // code that doing something with the client message ... 
        }
    }
}

现在,我不确定当我想停止侦听器状态时如何确保线程安全(将 listenerEnable 更改为 false)。

此外,当我想在不停止服务器侦听器状态的情况下(以某种分离的方法)向客户端发送一些消息时,我不确定如何保证该线程的安全。

感谢您的帮助。

【问题讨论】:

    标签: c# thread-safety tcplistener


    【解决方案1】:

    我建议等待事件而不是等待变量。在您当前的方案中,请考虑循环测试侦听器变量是否为真的情况。如果是,则进入循环并等待传入​​连接,然后阻塞。因此,现在即使另一个线程将侦听器变量设置为 false,您的循环也不会退出,直到有人连接到它并处理该连接。

    解决上述问题的一种方法是编写如下代码:

    WaitHandle[] waitHandles = new WaitHandle[] {endlLoopEvent};
    while(true)
    {
       int ret = WaitHandle.WaitAny(waitHandles, 100);
       if(WaitTimeout == ret) continue;
       else if(0 == ret) break; //our event has been signaled.
       else
        {
             if(!server.Pending()) continue; //Go back to the loop if no connection pending
             TcpClient client = server.AcceptTcpClient();  
             // You can spawn a thread to service the request.
        }
    }
    

    发送不会影响上面的循环,前提是它不是响应上面的连接请求。

    【讨论】:

      【解决方案2】:

      编写一个正确的、可扩展的套接字服务器并不简单——我建议你找到/购买一个——这已经做过很多次了。

      要回答您的问题,您的问题是 AcceptTcpClient 是一个阻塞呼叫。您将需要使用以 BeginXXXEndXXX 开头的 APM(异步编程模型)方法,例如 MSDN BeginAcceptTcpClient

      这些方法不会阻塞线程,但您必须处理并发。

      【讨论】:

        猜你喜欢
        • 2017-03-14
        • 1970-01-01
        • 2012-12-26
        • 1970-01-01
        • 1970-01-01
        • 2012-05-13
        • 2016-03-17
        • 2011-10-06
        • 2011-05-18
        相关资源
        最近更新 更多