简体   繁体   English

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

[英]How do i pause a loop in C# to wait for a user interaction?

In my program there is a loop that only stops if the user presses a certain button. 在我的程序中有一个循环,只有在用户按下某个按钮时该循环才会停止。 Now I want to give the user a certain amount of time to press the button. 现在,我想给用户一定的时间来按下按钮。 I change the color of the button to show the user that the stop-button is now active. 我更改按钮的颜色,以向用户显示停止按钮现在处于活动状态。

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;

It seems like there is not a "real" 2 second stop because the color does NOT to green at all. 似乎没有“真正的” 2秒停靠,因为颜色根本不会变绿。

The thread you are putting to sleep is the same thread that is responsible for drawing the application. 您要进入睡眠状态的线程与负责绘制应用程序的线程相同。 Hence calling Sleep here will simply stop application processing. 因此,在此处调用Sleep将仅停止应用程序处理。 This is definitely not what you want to do. 这绝对不是您想要执行的操作。

The better way to approach this problem is to use a Timer object. 解决此问题的更好方法是使用Timer对象。 Stop the processing, change the button color and setup a Timer to fire in 2 seconds time. 停止处理,更改按钮颜色,并将Timer设置为在2秒内触发。 If the button is pressed earlier stop the timer, else if the timer event fires then restart the processing. 如果较早按下按钮,则停止计时器,否则,如果计时器事件触发,则重新开始处理。 This method will allow the application to continue to run during the 2 second window 此方法将允许应用程序在2秒的窗口内继续运行

You're blocking the UI thread, and because of that no other updates to the user interface can take place until you free it up again. 您正在阻止UI线程,因此,除非再次释放它,否则无法对用户界面进行其他任何更新。 You need to use asynchrony here; 您需要在此处使用异步; let the UI thread stop executing your method and continue handling other requests. 让UI线程停止执行您的方法并继续处理其他请求。

Fortunately the await keyword makes doing this much easier than other methods. 幸运的是,使用await关键字使此操作比其他方法容易得多。

First we'll just create a helper method to generate a task that will be completed when a button is clicked: 首先,我们将只创建一个辅助方法来生成一个任务,该任务将在单击按钮时完成:

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

Now we can easily wait until either 2 seconds have passed, or the button is clicked: 现在,我们可以轻松地等待,直到经过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;
}

It seems your UI is freezing and you can't see the cahgnes.Instead try this, make your method async then use await 您的UI似乎冻结了,您看不到cahgnes。相反,请尝试将此方法设为async然后使用await

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

    await Task.Delay(2000); 

    this.button.BackColor = Color.White;
}

You should not use Thread.Sleep() as it hangs your UI. 您不应使用Thread.Sleep()挂起UI。

Try This: 尝试这个:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM