等待几秒钟,不会阻止UI执行
我想在两条指令之间等待几秒钟,但不阻止执行。
例如, Thread.Sleep(2000)
它不好,因为它阻止执行。
这个想法是,我调用一个方法,然后等待X秒(例如20)听一个事件来。 在20秒结束时,我应该根据20秒内发生的情况做一些操作。
我想你以后是Task.Delay。 这不会像Sleep那样阻塞线程,这意味着您可以使用asynchronous编程模型使用单个线程来执行此操作。
async Task PutTaskDelay() { await Task.Delay(5000); } private async void btnTaskDelay_Click(object sender, EventArgs e) { await PutTaskDelay(); MessageBox.Show("I am back"); }
我用:
private void WaitNSeconds(int segundos) { if (segundos < 1) return; DateTime _desired = DateTime.Now.AddSeconds(segundos); while (DateTime.Now < _desired) { System.Windows.Forms.Application.DoEvents(); } }
这是使用另一个线程的好例子:
// Call some method this.Method(); Task.Factory.StartNew(() => { Thread.Sleep(20000); // Do things here. // NOTE: You may need to invoke this to your main thread depending on what you're doing });
上面的代码需要.NET 4.0或更高版本,否则请尝试:
ThreadPool.QueueUserWorkItem(new WaitCallback(delegate { Thread.Sleep(20000); // Do things here }));
奥马尔的解决scheme是体面的*如果你不能升级你的环境到.NET 4.5,以获得访问asynchronous和等待的API。 也就是说,这里有一个重要的变化,以避免performance不佳。 在对Application.DoEvents()的调用之间应该稍加延迟,以防止CPU使用率过高。 通过增加
Thread.Sleep(1);
在调用Application.DoEvents()之前,可以添加这样的延迟(1毫秒),并阻止应用程序使用所有可用的CPU周期。
private void WaitNSeconds(int seconds) { if (seconds < 1) return; DateTime _desired = DateTime.Now.AddSeconds(seconds); while (DateTime.Now < _desired) { Thread.Sleep(1); System.Windows.Forms.Application.DoEvents(); } }
*有关使用Application.DoEvents()的潜在缺陷的更详细的讨论,请参阅https://blog.codinghorror.com/is-doevents-evil/ 。
如果你不想阻塞的东西,也不想使用multithreading,这是你的解决scheme: https : //msdn.microsoft.com/en-us/library/system.timers.timer(v=vs。 110)的.aspx
UI线程没有被阻塞,并且定时器在等待2秒钟之后才做。
以下是来自以上链接的代码:
// Create a timer with a two second interval. aTimer = new System.Timers.Timer(2000); // Hook up the Elapsed event for the timer. aTimer.Elapsed += OnTimedEvent; aTimer.Enabled = true; Console.WriteLine("Press the Enter key to exit the program... "); Console.ReadLine(); Console.WriteLine("Terminating the application...");
我真的对你使用Thread.Sleep(2000)
不利,因为几个原因( 这里有一些描述),但最重要的是因为它在debugging/testing时没有用处。
我build议使用C#Timer而不是Thread.Sleep()
。 定时器让你经常执行方法(如果有必要的话),并且在testing中使用很简单! 有一个非常好的例子,就是如何在超链接后面使用一个定时器 – 把你的逻辑“2秒后发生什么”放到Timer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
方法。
看看System.Threading.Timer
类。 我想这是你要找的。
MSDN上的代码示例似乎显示这个类与您正在尝试执行的操作非常相似(在特定时间后检查状态)。