如何让线程中的TcpClient停止?

时间:2010-06-19 22:20:21

标签: c# .net-4.0 multithreading

我有一个在tcpConnect方法之后运行的线程。我希望通过将Program.PrepareExit设置为true来在任何给定时间停止它。但是我的计划仍然停留在:
Int32 bytes = stream.Read(data, 0, data.Length);并没有真正对Program.PrepareExit设置为true做出反应。当我这么说时,我怎么能让它总是退出?

    public static readonly Thread MyThreadTcpClient = new Thread(ThreadTcpClient);
    private static void ThreadTcpClient() {
        Connections.tcpConnect(ClientTcpIp, ClientTcpPort);
    }

         public static void Main() {

             MyThreadTcpClient.Start();
             .... some code....
             Program.PrepareExit = true;
        }

    public static bool tcpConnect(string varClientIp, int varClientPort) {
        var client = new TcpClient();
        try {
            client = new TcpClient(varClientIp, varClientPort) {NoDelay = true};
            NetworkStream stream = client.GetStream();
            var data = new Byte[256];
            while (!Program.PrepareExit) {
                Int32 bytes = stream.Read(data, 0, data.Length);
                string varReadData = Encoding.ASCII.GetString(data, 0, bytes);
                if (varReadData != "" && varReadData != "echo") {
                    VerificationQueue.EnqueueRelease(varReadData);
                }
            }
        } catch (ArgumentNullException e) {
            MessageBox.Show(e.ToString(), "ArgumentNullException");
            tcpConnect(varClientIp, varClientPort);
        } catch (SocketException e) {
            MessageBox.Show(e.ToString(), "SocketException");
            tcpConnect(varClientIp, varClientPort);
        } catch (IOException e) {
            if (e.ToString() != "Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.") {
            }
            MessageBox.Show(e.ToString());
            tcpConnect(varClientIp, varClientPort);
        } finally {
            client.Close();
        }
        return false;
    }

1 个答案:

答案 0 :(得分:2)

有三个选项可供选择:

  • 使线程成为守护进程(背景)线程。当唯一的活动线程是守护程序线程时,该进程将退出
  • 在读取调用上设置超时,可能必须更改为使用底层套接字API。说实话,这不会很漂亮。
  • 使用异步IO。也有点痛苦。

在有序关闭方面,您是否需要此线程来执行任何?如果没有,守护程序线程方法可能是最简单的。