【问题标题】:Thread not really sleeping?线程不是真的在睡觉?
【发布时间】:2013-05-16 07:48:43
【问题描述】:

我正在尝试在用户单击Enter 后将TextBox 禁用几秒钟:

<StackPanel>
    <TextBox x:Name="txt1" Width="150" Margin="10" KeyUp="txt1_KeyUp"/>
</StackPanel>   

private void txt1_KeyUp(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Enter)
        {
            txt1.IsEnabled = false;
            Thread.Sleep(2500);
            txt1.IsEnabled = true; //all text is added here
        }
    }

如果我在Thread 处于休眠状态时继续输入,那么当Thread“醒来”时,我输入的所有内容都会在TextBox 中弹出。

我的问题是,当 GUI 线程处于休眠状态时,是否有某种缓冲区可以存储所有引发的事件?

【问题讨论】:

  • 你不应该真的让 UI 线程休眠。而是禁用文本框并安排任务稍后重新启用它。
  • 我意识到休眠 UI 线程不是正确的选择,但是我的问题更多是关于 Thread.Sleep 方法的工作原理。
  • 您正在休眠 UI 线程,因此您输入的文本的关键事件需要等待。此外,您可能会发现您的 UI 在这 2.5 秒内没有响应,即按 Enter 键然后尝试调整窗口大小。回答您的问题没有缓冲,但它们将被阻止,因为它们都在您停止执行的一个线程上运行。
  • @TheKingDave 所以所有事件都在“等待”直到线程唤醒,而不是被应用到应用程序上?
  • Windows 中的 UI 本质上是单线程的,并且使用消息泵工作。消息被添加到泵的队列中并使用 UI 线程进行处理。如果你阻塞线程,它不能处理消息,直到它再次被唤醒。

标签: c# wpf thread-sleep


【解决方案1】:

这里有一个更好的解决方案:

<StackPanel>
    <TextBox x:Name="txt1" Width="150" Margin="10" KeyUp="txt1_KeyUp"/>
</StackPanel>   

private void txt1_KeyUp(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Enter)
    {
        txt1.IsEnabled = false;
        Thread t = new Thread(() =>
        {
            System.Threading.Thread.Sleep(2500);
            Action action = () => txt1.IsEnabled = true;
            Dispatcher.Invoke(action);
        });
        t.Start();
    }
}

您会看到,当您按 Enter 时,该框被禁用并且您没有在 UI 线程上休眠。

如果您希望其他 UI 元素知道何时完成,您可以将 t(线程)保存到表单中,您可以查询它的状态 (t.ThreadState) 以确定它是否已完成。

【讨论】:

    猜你喜欢
    • 2020-08-05
    • 1970-01-01
    • 1970-01-01
    • 2011-10-19
    • 2012-08-08
    • 2011-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多