C#.NET在接受分体线程和应用程序退出UDP包 [英] C# .Net receiving UDp packets in separater thread and application exit

查看:139
本文介绍了C#.NET在接受分体线程和应用程序退出UDP包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的Winforms应用,我在UDP中专用线程接收数据和每一个新的数据分组已被接收的时间引发事件。该应用程序工作正常,但问题是,在应用程序退出时,UDP监听保持侦听,从而保持应用程序的运行。

In my Winforms application, I am receiving data over UDP in a dedicated thread and raising an event every time a new data packet has been received. The application works fine, but the problem is that in the application exit, the UDP listener keeps listening and thus keeps the app running.

线程还不是很熟悉的话题给我,所以我的问题是什么是关闭UDP监听线程的正确方法?另外,我想知道为什么犯规的UDP监听退出while循环,当我打电话StopListener()主线程。

Threading is not very familiar topic to me, so my question is what is the correct way to close the UDP listening thread? Also, I would like to understand why doesnt the UDP listener exit the while loop when I call the StopListener() from the main thread.

我的UDP监听器看起来是这样的:

My UDP listener looks like this:

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线程)我做到以下几点:

And in the MainWindow_FormClosing() event (in the main UI thread) I do the following:

  m_udpListener.StopListener();
  this.m_udpListener.NewMessageReceived -= OnNewMessageReceived;

应用程序现在工作的方式是施药后退出,应用程序已挂,但下一个接收UDP数据包中的UDP监听器引发了异常,然后finally块被执行,而不是之前。

The way the app works now is after application exit, the application is left hanging, but the next received UDP packet raises an exception in the UDP listener, and then the finally block gets executed, but not before.

显然我误解的东西,帮助将不胜感激!

Clearly I have misunderstood something, help would be appreciated!

推荐答案

您的代码看起来不错,但你可以添加几行,使关闭更可靠。

Your code looks OK but you can add a few lines to make Closing more reliable.

public void StopListener()
{
    this.listening = false;            
    listener .Close();   // forcibly end communication 
}



停车需要一点时间,因此,早调用此尽可能(即从关闭按钮,而不是从WINDOW_CLOSED事件):

Stopping requires a little time, so call this as early as possible (ie from the Close button and not from Window_Closed event) :

  // first disconnect the event
  this.m_udpListener.NewMessageReceived -= OnNewMessageReceived;
  m_udpListener.StopListener(); 
  Application.DoEvents();          // allow processing of outstanding packets 



虽然它应该不是很关键,我会做的主题背景之一:

And although it should not critical, I would make the Thread a background one:

     m_ListeningThread = new Thread(ListenForUDPPackages);
     m_ListeningThread.IsBackground = true;

这篇关于C#.NET在接受分体线程和应用程序退出UDP包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆