2

我有一个主窗体类和另一个类。在第二堂课中,我有一个线程循环:

    public void StartListening()
    {
        listening = true;
        listener = new Thread(new ThreadStart(DoListening));
        listener.Start();
    }


    // Listening for udp datagrams thread loop
    /*=====================================================*/
    private void DoListening()
    {
        while (listening)
        {
            IPEndPoint remoteIPEndPoint = new IPEndPoint(IPAddress.Any, port);
            byte[] content = udpClient.Receive(ref remoteIPEndPoint);

            if (content.Length > 0)
            {
                string message = Encoding.ASCII.GetString(content);
                delegMessage(message);
            }
        }
    }

    // Stop listening for udp datagrams
    /*=====================================================*/
    public void StopListening()
    {
        lock (locker)
        {
            listening = false;
        }
    }

在主窗体类中,我在类构造函数中开始监听

       udp.StartListening();

而且,在这个主窗体类中,我也有关键钩子事件。在这种情况下,我想停止在第二类中运行的线程。

    private void hook_KeyPressed(int key)
    {
        if (key == (int)Keys.LMenu)
            altPressed = true;
        if (key == (int)Keys.F4 && altPressed == true)
        udp.StopListening();
    } 

不幸的是,线程仍在运行。你对此有一些想法吗?

非常感谢。

4

3 回答 3

4

您的线程阻塞byte[] content = udpClient.Receive(ref remoteIPEndPoint);在线。Receive 方法会阻塞,直到收到某些内容。

您应该改用异步版本 ( BeginReceive )。

于 2013-09-23T13:30:13.720 回答
1

此外,您的代码中的另一个缺陷 - 您在没有任何同步的情况下检查停止条件。这里:

   private void DoListening()
   {
    while (listening){ //this condition could stuck forever in 'false'
   }

实际上,如果没有内存屏障,就无法保证正在运行的线程DoListening会看到listening其他线程对 var 的更改。您至少应该在这里使用锁定(提供内存屏障)

于 2013-09-23T13:34:27.723 回答
1

正如@igelineau 指出的那样 - 您的代码阻塞了接收呼叫。如果您不想走异步路线(我建议),只需在您的停止侦听方法中向 udp 端口​​发送一些东西。

于 2013-09-23T13:37:19.927 回答