none
關於thread無法正確關閉的問題 RRS feed

  • 問題

  • 下面的程式,是我設定一個udpclient,當我按下receive時,

     

    就一直去接收字串,並顯示,但是我按下close時,我想要終止thread,

     

    但是thread一直無法終止,想請問大家,有什麼好方法,可以正常的終止它。

     

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows.Forms;
    using System.Net;
    using System.Net.Sockets;
    using System.Threading;

    namespace udpPDA
    {
        public partial class PDA : Form
        {
            UdpClient udpPDA;
            IPEndPoint PC_ipEndPoint;
            Thread ReceiveStreamDataThread;
            Byte[] receiveBytes;
            public PDA()
            {
                InitializeComponent();
            }

            private void PDA_Load(object sender, EventArgs e)
            {
                udpPDA = new UdpClient(2000);//listen 本端 PORT: 2000
                IPAddress ipAddress = IPAddress.Parse("140.125.33.172");
                PC_ipEndPoint = new IPEndPoint(ipAddress, 1000);//PC 端的IP & PORT                     
            }

            private void receive_Click(object sender, EventArgs e)

            {
                try{
                    ReceiveStreamDataThread = new Thread(new ThreadStart(ReceiveStream));
                    ReceiveStreamDataThread.Start();
                    receivetextBox.Text = "receive start"; 
                }
                catch (Exception ex){
                    errortextBox.Text = ex.ToString();
                }
            }

            private void close_Click(object sender, EventArgs e)
            {
                ReceiveStreamDataThread.Abort();
                receivetextBox.Text = "receive thread close";
            }   
            void ReceiveStream()
            {
                while (true)
                {
                    receiveBytes = udpPDA.Receive(ref PC_ipEndPoint);
                    string ReceiveData = Encoding.ASCII.GetString(receiveBytes);
                    receivetextBox.Text = ReceiveData;
                }
            }            
        }
    }

    2008年4月1日 上午 11:16

解答

  • 你希望每次按鈕按下"多一個"執行緒等待udp client傳來的資料嗎, 如果不是的話不需要用到多執行緒

    我會建議你用非同步Socket

    程式碼如下

     

    Code Snippet

    bool recvflag = false;
    private void button1_Click(object sender, System.EventArgs e)
    {
      if (!recvflag)
      {
        s = new Socket(AddressFamily.InterNetwork,SocketType.Dgram, ProtocolType.Udp);     
        server.Bind(iep);          
        byte[] d = new byte[128]; 
        server.BeginReceive(d,0,d.Length,SocketFlags.Peek,new AsyncCallback(Recv), null);  
        button1.Text = "結束";
      }
      else
      {
        s.Close();
        recvflag =  false;
        button1.Text = "開始";
      }
    }  

    void Recv(IAsyncResult iar)
    {
      try
      {
        int len = s.EndReceive(iar);
        byte[] d = new byte[128]; 
        if (len > 0)
        {
          s.Receive(d, sent, SocketFlags.None);
          string text = Encoding.ASCII.GetString(d);
          listBox1.Items.Add(text);
        }
        s.BeginReceive(d,0,d.Length,SocketFlags.Peek,new AsyncCallback(Recv), null);
      }
      catch (Exception e)
      {
        System.Diagnostics.Debug.WriteLine(e.Message);
      }
    }

     

     

    也就是說每次按鈕按下會啟動非同步UdpServer, 按鈕再次按下則會結束Server

    希望這是你要的 Smile

    2008年4月6日 下午 07:59

所有回覆

  •  

    用 Abort( ) 太猛了一點,將被停掉的 Thread 會引發 Exception,通常要停掉一個 Thread 讓它正常的 RETURN 比較好。

     

    方法很簡單,改變一個變數,在你的 while loop 裡判段這個變數的值就可以了。可以省掉不少麻煩事

    2008年4月3日 下午 01:51
  • 你希望每次按鈕按下"多一個"執行緒等待udp client傳來的資料嗎, 如果不是的話不需要用到多執行緒

    我會建議你用非同步Socket

    程式碼如下

     

    Code Snippet

    bool recvflag = false;
    private void button1_Click(object sender, System.EventArgs e)
    {
      if (!recvflag)
      {
        s = new Socket(AddressFamily.InterNetwork,SocketType.Dgram, ProtocolType.Udp);     
        server.Bind(iep);          
        byte[] d = new byte[128]; 
        server.BeginReceive(d,0,d.Length,SocketFlags.Peek,new AsyncCallback(Recv), null);  
        button1.Text = "結束";
      }
      else
      {
        s.Close();
        recvflag =  false;
        button1.Text = "開始";
      }
    }  

    void Recv(IAsyncResult iar)
    {
      try
      {
        int len = s.EndReceive(iar);
        byte[] d = new byte[128]; 
        if (len > 0)
        {
          s.Receive(d, sent, SocketFlags.None);
          string text = Encoding.ASCII.GetString(d);
          listBox1.Items.Add(text);
        }
        s.BeginReceive(d,0,d.Length,SocketFlags.Peek,new AsyncCallback(Recv), null);
      }
      catch (Exception e)
      {
        System.Diagnostics.Debug.WriteLine(e.Message);
      }
    }

     

     

    也就是說每次按鈕按下會啟動非同步UdpServer, 按鈕再次按下則會結束Server

    希望這是你要的 Smile

    2008年4月6日 下午 07:59
  • 我必須用同步的…因為我要用至pda

     

    2008年5月20日 上午 02:31