【问题标题】:C# thread started in another classC# 线程在另一个类中启动
【发布时间】:2013-09-23 13:23:22
【问题描述】:

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

    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();
    } 

不幸的是,线程仍在运行。 您对此有什么想法吗?

非常感谢。

【问题讨论】:

  • 你有没有调试过你的while(listening)循环你调用StopListening来检查状态是否真的改变了?
  • 你调试过StopListening是否被执行了吗?
  • 是的,我试过了,问题是“听”还是真的。

标签: c# multithreading events


【解决方案1】:

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

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

【讨论】:

  • 非常感谢,我去看看。
【解决方案2】:

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

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

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

【讨论】:

  • 一个有效的观点,但我不喜欢弄乱 volatile,除非绝对必要:albahari.com/threading/…
  • 你是对的。不幸的是,我还不精通线程同步...
  • @undefined 哇。好吧,如果 Joe Duffy 和 Joseph Albahari 说要小心,那绝对是个好主意。
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-03
    • 1970-01-01
    • 1970-01-01
    • 2016-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多