如何在方法二中调用方法一中创建的线程,且每次调用方法二时都需要关闭此线程?

将此两个方法保存在一个新建类中,通过构造函数传递线程,每次调用方法时,都创建一个新的类的实例,实际操作的是该线程的形参

代码如下:

复制代码
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;
        }
    }
}
复制代码

 

posted @   xiaoxinZard  阅读(174)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示