C#.Net在分离线程和应用程序出口中接收UDp数据包
本文关键字:UDp 数据包 出口 应用程序 Net 分离 线程 | 更新日期: 2023-09-27 18:21:45
在我的Winforms应用程序中,我在一个专用线程中通过UDP接收数据,每次收到新的数据包时都会引发一个事件。应用程序运行良好,但问题是在应用程序出口中,UDP侦听器一直在侦听,从而使应用程序保持运行。
线程对我来说不是很熟悉的话题,所以我的问题是关闭UDP侦听线程的正确方法是什么?此外,我想了解当我从主线程调用StopListener()时,UDP侦听器为什么不退出while循环。
我的UDP侦听器如下所示:
class UDPListener
{
private int m_portToListen = 2003;
private volatile bool listening;
Thread m_ListeningThread;
public event EventHandler<MyMessageArgs> NewMessageReceived;
//constructor
public UDPListener()
{
this.listening = false;
}
public void StartListener(int exceptedMessageLength)
{
if (!this.listening)
{
m_ListeningThread = new Thread(ListenForUDPPackages);
this.listening = true;
m_ListeningThread.Start();
}
}
public void StopListener()
{
this.listening = false;
}
public void ListenForUDPPackages()
{
UdpClient listener = null;
try
{
listener = new UdpClient(m_portToListen);
}
catch (SocketException)
{
//do nothing
}
if (listener != null)
{
IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, m_portToListen);
try
{
while (this.listening)
{
Console.WriteLine("Waiting for UDP broadcast to port " +m_portToListen);
byte[] bytes = listener.Receive(ref groupEP);
//raise event
NewMessageReceived(this, new MyMessageArgs(bytes));
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
finally
{
listener.Close();
Console.WriteLine("Done listening for UDP broadcast");
}
}
}
}
public class MyMessageArgs : EventArgs
{
public byte[] data { get; set; }
public MyMessageArgs(byte[] newData)
{
data = newData;
}
}
在MainWindow_FormClosing()事件中(在主UI线程中),我执行以下操作:
m_udpListener.StopListener();
this.m_udpListener.NewMessageReceived -= OnNewMessageReceived;
应用程序现在的工作方式是在应用程序退出后,应用程序保持挂起状态,但下一个接收到的UDP数据包在UDP侦听器中引发异常,然后执行finally块,但在此之前不会执行。
很明显,我误解了什么,请帮忙!
我知道这个线程有点旧,但我在查找UDP信息时偶然发现了它。
无论如何,监听false的原因设置不退出while循环?
byte[] bytes = listener.Receive(ref groupEP);
是阻塞等待接收字节的线程。请参阅UdpClient.接收方法
while (this.listening)
只有在接收到字节后才会进行检查。到那时已经很晚了。
您的代码看起来不错,但您可以添加几行代码,使Closing更加可靠。
public void StopListener()
{
this.listening = false;
listener .Close(); // forcibly end communication
}
停止需要一点时间,所以请尽早调用(即从关闭按钮而不是从Window_Closed事件):
// first disconnect the event
this.m_udpListener.NewMessageReceived -= OnNewMessageReceived;
m_udpListener.StopListener();
Application.DoEvents(); // allow processing of outstanding packets
虽然它不应该是关键的,但我会把线程作为一个背景:
m_ListeningThread = new Thread(ListenForUDPPackages);
m_ListeningThread.IsBackground = true;
我曾经在那里,你的代码还可以,只是一个线程误解了如何安全地打开和关闭线程,只需阅读以下内容:http://msdn.microsoft.com/en-us/library/system.threading.threadstart(v=vs.110).aspx
编辑代码中的这一行:
m_ListeningThread = new Thread(new ThreadStart(ListenForUDPPackages));