1. 程式人生 > 實用技巧 >如何在方法二中呼叫方法一中建立的執行緒,且每次呼叫方法二時都需要關閉此執行緒?

如何在方法二中呼叫方法一中建立的執行緒,且每次呼叫方法二時都需要關閉此執行緒?

將此兩個方法儲存在一個新建類中,通過建構函式傳遞執行緒,每次呼叫方法時,都建立一個新的類的例項,實際操作的是該執行緒的形參

程式碼如下:

using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets; 
using System.Threading;

namespace Intelligent_Control
{
    class CommunicateByUDP
    {
        private Tools tools = new Tools();

        
private Thread udpListeningThread = null; //UDP監聽接收資料執行緒 private UdpClient udpclient = new UdpClient(8090); //UDPClient private List<byte> receiveBufferList = new List<byte>(); //UDP接收資料快取 private List<string> _devipList = new List<string
>(); //儲存搜尋到的裝置 private bool udpPortStatus = false; //UDP埠狀態(是否開啟) private string debugText = ""; //除錯日誌資訊 //public List<string> udphistory = new List<string>(); //儲存UDP連線的歷史記錄 //public List<string> ipList = new List<string>();
//裝置IP集合 public CommunicateByUDP(ref List<string> _devipList, ref List<byte> receiveBufferList, byte[] sendFrame, string targetHost, int targetPort, Thread udpListeningThread) { this._devipList = _devipList; this.receiveBufferList = receiveBufferList; this.udpListeningThread = udpListeningThread; this.receiveBufferList.Clear(); OpenUdpListening(); SendFrame(targetHost, targetPort, sendFrame); CloseUdpListening(); } /// <summary> /// 開啟一個新執行緒,用於執行——監聽udpclient接收資訊的方法 /// </summary> public void OpenUdpListening() { try { udpListeningThread = new Thread(new ThreadStart(ReceiveData));//接收資料執行緒 udpListeningThread.IsBackground = true; udpListeningThread.Start(); udpPortStatus = true; } catch (Exception ex) { debugText += (ex + "\r\n"); udpPortStatus = false; } } /// <summary> /// 傳送資料幀給目標ip的目標埠 /// </summary> /// <param name="targetHost">目標ip</param> /// <param name="targetPort">目標埠</param> /// <param name="sendFrame">需要傳送的資料幀</param> /// <returns></returns> public bool SendFrame(string targetHost,int targetPort,byte[] sendFrame) { try { if (!udpPortStatus) { debugText += "!udpPortStatus導致未連線\r\n"; return false; } //receiveBufferList.Clear(); //清空快取 udpclient.Send(sendFrame, sendFrame.Length, targetHost, targetPort); if (!WaitCheckDev(100)) //超時判定,如若不新增此判定,Receive方法可能會阻塞 { debugText += "!waitCheckDev導致未連線\r\n"; return false; } return true; } catch (Exception e) { debugText += (e + "\r\n"); return false; } } /// <summary> /// 監聽udpclient接收的資訊 /// </summary> public void ReceiveData() { try { while (true) { IPEndPoint myhost = null; byte[] buffer = udpclient.Receive(ref myhost); debugText += ("\r\n" + "接受到資料的長度:" + buffer.Length + "\r\n"); for (int i = 0; i < buffer.Length; i++) { debugText += ("接收到第" + i + "個數據:" + buffer[i] + "\r\n"); } EndPoint Remote = myhost; string[] strList = tools.SplitPage(Remote.ToString(), ":"); string Ip = strList[0]; string Point = strList[1]; if (!_devipList.Contains(Ip)) { _devipList.Add(Ip); } receiveBufferList.AddRange(buffer);//接收的資料加入快取 } } catch (Exception ex) { udpPortStatus = false; debugText += (ex + "\r\n"); } } /// <summary> /// 訊息傳送完畢後,關閉udp通訊 /// </summary> public void CloseUdpListening() { try { int listCountBefore = -1; while (true) { if (receiveBufferList.Count == listCountBefore)//當緩衝區不在增加資料時,關閉執行緒 { udpListeningThread.Abort(); break; } Thread.Sleep(50); listCountBefore = receiveBufferList.Count; } } catch (Exception e) { debugText += ("關閉UDP通訊時錯誤" + e); } try { if (udpPortStatus) { udpclient.Close(); //關閉UDP通訊 } udpPortStatus = false; } catch(Exception e) { debugText += ("關閉UDP通訊錯誤\r\n" + e); } } /// <summary> /// 通訊超時判定 /// </summary> /// <param name="timeout"></param> /// <returns></returns> private bool WaitCheckDev(int timeout) { int times = 0; if (timeout == 0) { //timeout為0,意味不用等待 return true; } while (true) { if (receiveBufferList.Count > 0) { break; //有返回即可 } tools.Delay(10); //等待10ms times++; if (times > (timeout / 10)) { //超時 return false; } } return true; } } }