【问题标题】:How to close a TcpClient opened in a Thread Properly如何正确关闭在线程中打开的 TcpClient
【发布时间】:2014-11-24 14:42:17
【问题描述】:

我通过Thread 连接到TcpClient。现在TcpClient 的连接在线程中正确打开,但TcpClient 关闭并且线程没有正常发生。我不知道为什么。

这是我开始的主题:

 private System.Threading.Thread _thread;
 private ManualResetEvent _shutdownEvent = new ManualResetEvent(false); 

_thread = new Thread(DoWork);
_thread.Start();

这里是TcpClient 连接:

private void DoWork()
{
while (!_shutdownEvent.WaitOne(0))
{                           
    try
    {
        client = new TcpClient();
        client.Connect(new IPEndPoint(IPAddress.Parse(ip),intport));
        //Say thread to sleep for 1 secs.
        Thread.Sleep(1000);
    }
    catch (Exception ex)
    {
        // Log the error here.
        client.Close();
        continue;
    }
    try
    {
        using (stream = client.GetStream())
        {

           byte[] notify = Encoding.ASCII.GetBytes("Hello");
           stream.Write(notify, 0, notify.Length);

            byte[] data = new byte[1024];
            while (!_shutdownEvent.WaitOne(0))
            {
                int numBytesRead = stream.Read(data, 0, data.Length);
                if (numBytesRead > 0)
                {
                    line= Encoding.ASCII.GetString(data, 0, numBytesRead);
                }
            }
            ...

现在这里是关闭和重启线程和TcpClient的代码:

 _shutdownEvent.WaitOne(0);
 _thread.Abort();

 //Start Again
 _thread = new Thread(DoWork);
 _thread.Start();

请帮助我正确停止和启动线程和TcpClient。 谢谢。

【问题讨论】:

    标签: c# multithreading sockets tcp tcpclient


    【解决方案1】:

    将 _shutdownEvent 声明为 AutoResetEvent。

    AutoResetEvent _shutdownEvent = new AutoResetEvent(false);
    

    去掉Dowork方法中的外层while循环

    private void DoWork()
        {
            try
            {
                client = new TcpClient();
                client.Connect(new IPEndPoint(IPAddress.Parse(ip), intport));
                //Say thread to sleep for 1 secs.
                Thread.Sleep(1000);
            }
            catch (Exception ex)
            {
                // Log the error here.
                client.Close();
                return;
            }
            try
            {
                using (stream = client.GetStream())
                {
                    byte[] notify = Encoding.ASCII.GetBytes("Hello");
                    stream.Write(notify, 0, notify.Length);
    
                    byte[] data = new byte[1024];
                    while (!_shutdownEvent.WaitOne(0))
                    {
                        int numBytesRead = stream.Read(data, 0, data.Length);
                        if (numBytesRead > 0)
                        {
                            line = Encoding.ASCII.GetString(data, 0, numBytesRead);
                        }
                    }
                }
            }
            catch
            {
            }
            finally
            {
                if (stream != null)
                    stream.Close();
                if (client != null)
                    client.Close();
            }        
        }
    

    使用_shutdownEvent.Set() 发出事件信号。

    _shutdownEvent.Set(); //Set, not Wait
    //_thread.Abort(); //and you don't have to abort the thread since it will end gracefully after it break out of the while loop
    while (_thread.IsAlive) ; //wait until the first thread exit
    
    //Start Again
    _thread = new Thread(DoWork);
    _thread.Start();
    

    【讨论】:

    • 我无法使用给定的代码重新启动 TcpClient(); 客户端
    • _thread = new Thread(DoWork); _thread.Start(); 使用此代码我无法在 Dowork() 方法处获得断点..
    • @HansPassant 你能指导我到合适的方式吗..Thnks
    • @HansPassant 因为 ManualResetEvent 的状态在等待成功后不会重置为非信号状态。所以我们需要一个 AutoResetEvent。
    • 但我无法再次启动线程.._thread = new Thread(DoWork); _thread.Start();
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-15
    • 1970-01-01
    • 2014-06-11
    • 1970-01-01
    • 1970-01-01
    • 2013-05-11
    相关资源
    最近更新 更多