C#中切记程序结束时检查是否所有线程均关闭

之前写的一个tcp协议的聊天室,每次点击窗口的*关闭程序后,再次开启该程序出现端口被占用的情况,

仔细检查源码后才发现原来C#中如果用winform编程的话主线程关闭时如果没有显式的关闭子线程,子线程会继续运行

 

以下是源码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Threading;
using System.Text.RegularExpressions;
using System.IO;
using System.Collections;

namespace ChatServer
{
    public partial class Form1 : Form
    {
        public Hashtable ht = new Hashtable();

        private Thread tcplistenerthread;
        private Thread messagethread;
        private TcpListener tl;
        public Form1()
        {
            InitializeComponent();
        }



        private void start_Click(object sender, EventArgs e)
        {
            //this.richTextBox1.Text += new JavaService.SayHelloPortTypeClient().example("中国");
            this.start.Enabled=false;
            tl = new TcpListener(int.Parse(this.textBox1.Text));
            tl.Start();
            tcplistenerthread = new Thread(new ParameterizedThreadStart(Listen));
            tcplistenerthread.Start(tl);
        }

        private void Listen(object tlistener)
        {
            TcpListener tl = (TcpListener)tlistener;
            tl.Start();
            while (true)
            {
                TcpClient tc = tl.AcceptTcpClient();
                this.richTextBox1.Text += "\n接收到新的客户端链接:" + tc.Client.RemoteEndPoint;
                messagethread = new Thread(new ParameterizedThreadStart(MessageThread));
                messagethread.Start(tc);
            }

        }

        private void MessageThread(object j)
        {
            TcpClient tc=(TcpClient)j;
            string key = tc.Client.RemoteEndPoint.ToString();
            this.listBox1.Items.Add(key);
            this.listBox1.Refresh();
            NetworkStream ns = tc.GetStream();
            StreamWriter sw = new StreamWriter(ns);
            StreamReader sr = new StreamReader(ns);
            ht.Add(key,sw);
            try
            {
                while (true)
                {
                    string ss=sr.ReadLine();
                    this.richTextBox1.Text += "\n"+ss;
                    this.richTextBox1.Refresh();     
            
                }   
            }
            
            catch (Exception e)
            
            {
            
                ht.Remove(key);
                
                this.listBox1.Items.Remove(key);
                
                this.listBox1.Refresh();
                
                this.richTextBox1.Text += "\n客户端"+key+"断开连接了";
                
                
                this.richTextBox1.Refresh();
                
            }
        }

        private void sender_Click(object sender, EventArgs e)
        {
            ListBox.SelectedObjectCollection lb = this.listBox1.SelectedItems;
            string text = this.textBox2.Text;
            foreach (string so in lb)
            {
                StreamWriter sw = (StreamWriter)ht[so];
                sw.WriteLine(text);
                sw.Flush();
                this.richTextBox1.Text += "\n" + so + ":" + text;
                this.richTextBox1.Refresh();
            }

        }

        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
        }

        private void Form1_Load(object sender, EventArgs e)
        {
        }

    

}

 

 

改进后增加了一个关闭事件

    private void Form1_FormClosed(object sender, EventArgs e)
        {
            //Thread.Sleep(2000);
            this.richTextBox1.Text += "测帅";
            if(messagethread!=null)
                messagethread.Abort();
            if(tcplistenerthread!=null)
               tcplistenerthread.Abort();
            if (tl != null)
            {
                tl.Stop();
                tl = null;
            }
        }
    }

 并且在form的初始化方法中增加事件监听控制器:

 

            this.FormClosed+=new FormClosedEventHandler(Form1_FormClosed);

 

测试后发现问题已解决

你可能感兴趣的:(C++,c,C#,LINQ,WinForm)