jar*_*man 5 .net c# multithreading udp
在我的 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;
}
}
Run Code Online (Sandbox Code Playgroud)
在 MainWindow_FormClosing() 事件中(在主 UI 线程中),我执行以下操作:
m_udpListener.StopListener();
this.m_udpListener.NewMessageReceived -= OnNewMessageReceived;
Run Code Online (Sandbox Code Playgroud)
应用程序现在的工作方式是在应用程序退出后,应用程序保持挂起,但下一个接收到的 UDP 数据包在 UDP 侦听器中引发异常,然后执行 finally 块,但不是之前。
显然我误解了一些东西,将不胜感激!
您的代码看起来不错,但您可以添加几行以使关闭更加可靠。
public void StopListener()
{
this.listening = false;
listener .Close(); // forcibly end communication
}
Run Code Online (Sandbox Code Playgroud)
停止需要一点时间,因此请尽早调用它(即从“关闭”按钮而不是从 Window_Closed 事件):
// first disconnect the event
this.m_udpListener.NewMessageReceived -= OnNewMessageReceived;
m_udpListener.StopListener();
Application.DoEvents(); // allow processing of outstanding packets
Run Code Online (Sandbox Code Playgroud)
尽管这不重要,但我会将线程设为背景线程:
m_ListeningThread = new Thread(ListenForUDPPackages);
m_ListeningThread.IsBackground = true;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10823 次 |
| 最近记录: |