【问题标题】:Threads UI and nightmares线程 UI 和噩梦
【发布时间】:2011-06-06 19:59:12
【问题描述】:

我有一个类在它启动的线程中处理一些实时操作。由于它非常复杂,因此在此应用程序中还有其他问题。当这个 rt 动作开始时,我需要弹出一个窗口并在完成后关闭它。听起来很简单。

当这个动作开始和停止时,我会挂钩一些事件。在这些事件处理程序中,我放置了代码:

        private void Voice_SpeakStarted(object sender, TMSpeakStartedEventArgs e)
    {

        InfoWindow = new Form();
        InfoWindow.Show();
    }

    /// <summary>
    /// this is the event handler speaking stops
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void Voice_SpeakCompleted(object sender, TMSpeakCompletedEventArgs e)
    {
        if (InfoWindow.InvokeRequired)
        {
            InfoWindow.Invoke(new Action(() =>
            {
                InfoWindow.Close();
            }));

            InfoWindow.Hide();
        }
    }

有时我收到线程已终止的错误。 (调用该方法时出错。目标线程不再存在。)

我似乎总是让窗口显示出来。我似乎无法关闭窗口。

我还看到有时处理程序本身不会被调用。

我非常需要帮助。如果有帮助,我可以发布更多代码。

已编辑 - 添加了更多代码 这就是我开始上课的方式

        public void start()
    {
        //It's already alive, nothing to do
        if (alive) return;

        //Make sure this is the only place where alive is set to true
        alive = true;

        Voice.SpeakCompleted += new Speech.TMSpeakCompletedDelegate(Voice_SpeakCompleted);
        Voice.SpeakStarted += new Speech.TMSpeakStartedDelegate(Voice_SpeakStarted);


        dispatch = new Thread(new ThreadStart(ProcessSayList));
        dispatch.Start();
    }

类的构造函数是

    public AnimationControl(dynamic parent)
    {
        Parent = parent;
        Voice = new Speech();

        q = Queue.Synchronized(new Queue(1000));
        start();
    }

【问题讨论】:

  • ProcessSayList 是什么?什么级别?添加一些上下文!

标签: winforms multithreading user-interface


【解决方案1】:

您应该真正专门化您的线程并停止从任何线程调用由其他线程管理的代码。使用消息队列将操作传达给您的线程。这是进行多线程的最安全方式。

伪代码示例:

Thread1
{
  while (1)
  {
    read my last message in my queue;
    do something according to this message like:
    openwindow();
    or closewindow();
  }
}

Thread2
{
  My life is short, I just need to post a message to thread1
}


Thread3
{
  etc.
}

在每个系统上都有现成的结构用于这样的事情。通过这样做,在出现此类问题时更容易理解正在发生的事情。当然,如果你不小心,你的线程程序可能会变成绝对线性的;目标是确保动作的某些部分可以并行进行,并且不会创建一个一个一个地等待彼此的线程链:)

【讨论】:

    【解决方案2】:

    在此处查看我的答案,了解有关线程终止错误和一般 UI 线程的一些信息:understanding InvalidAsynchronousStateException occurrences

    【讨论】:

      【解决方案3】:

      一方面,即使InvokeRequired 返回真,您在窗口上的错误线程上调用Hide

      我还可以猜测您正在新线程上创建 Voice 实例并在收到“关闭”消息时返回,因此有时会杀死您尝试路由 Windows 消息的线程。考虑保持线程直到您的窗口真正关闭。

      是的,您应该发布更多代码,没有一行代码可以显示您如何创建/处置该线程。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-21
        • 2020-03-14
        • 2010-11-13
        相关资源
        最近更新 更多