如何在C#中暂停循环以等待用户交互?

时间:2014-02-17 17:35:09

标签: c# loops thread-sleep

在我的程序中,有一个循环只有在用户按下某个按钮时才会停止。现在我想给用户一定的时间来按下按钮。我更改了按钮的颜色,向用户显示停止按钮现在处于活动状态。

this.button.Focus();

this.button.BackColor = Color.Green;

System.Threading.Thread.Sleep(2000);  

// now the loop continues and the button changes its color
this.button.BackColor = Color.White;

似乎没有“真正的”2秒停止,因为颜色根本不是绿色。

4 个答案:

答案 0 :(得分:1)

您要暂停的线程与负责绘制应用程序的线程相同。因此,在此处调用Sleep将简单地停止应用程序处理。这绝对不是你想要做的。

解决此问题的更好方法是使用Timer对象。停止处理,更改按钮颜色并设置Timer以在2秒内激活。如果按下按钮,则先停止计时器,否则如果计时器事件触发,则重新启动处理。此方法将允许应用程序在2秒窗口期间继续运行

答案 1 :(得分:1)

您正在阻止UI线程,因此在您再次释放之前,不会对用户界面进行任何其他更新。你需要在这里使用异步;让UI线程停止执行您的方法并继续处理其他请求。

幸运的是await关键字比其他方法更容易做到这一点。

首先,我们将创建一个辅助方法来生成一个任务,该任务将在单击按钮时完成:

public static Task WhenClicked(this Button button)
{
    var tcs = new TaskCompletionSource<bool>();
    EventHandler handler = null;
    handler = (s, e) =>
    {
        tcs.TrySetResult(true);
        button.Click -= handler;
    };
    button.Click += handler;
    return tcs.Task;
}

现在我们可以轻松等到2秒钟或点击按钮:

public  async void Bar()
{
    this.button.Focus();

    this.button.BackColor = Color.Green;

    await Task.WhenAny(Task.Delay(2000), button.WhenClicked());

    // now the loop continues and the button changes its color
    this.button.BackColor = Color.White;
}

答案 2 :(得分:0)

看来你的UI已经冻结了,你无法看到cahgnes.Instead尝试这个,让你的方法async然后使用await

public async void SomeMethod()
{
    this.button.BackColor = Color.Green;

    await Task.Delay(2000); 

    this.button.BackColor = Color.White;
}

答案 3 :(得分:0)

您不应使用Thread.Sleep(),因为它会挂起您的用户界面。

试试这个:

System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer();
timer1.Interval=2000;
timer1.Tick += new System.EventHandler(timer1_Tick);
timer1.Start();

private void timer1_Tick(object sender, EventArgs e)
{
     //do whatever you want 
     this.button.BackColor = Color.White;

    //Stop Timer
    timer1.Stop();
}