等待n秒钟,然后执行下一行代码而不冻结窗体。

17

嗨,我正在尝试找到一种在移动到下一行代码之前等待若干毫秒的方法。

我已经尝试使用Thread.Sleep,但这会冻结主表单,我希望它保持活动状态。

我尝试过计时器和秒表,但当它们应该在控制台发布时,两者都会冻结主表单。

我也找不到使用task.delay或background worker在我想要的等待中的方法。

伪代码:

Wait 2 - 6 seconds
Log "waiting"
Log "waiting"
Log "waiting"
Stop Waiting - Run next line of code.

我尝试过的方法会导致表单停止响应并在之后填写日志,我只想简单等待而不冻结表单,也不需要处理事件调用,这意味着下一行代码无法运行。

由于我对C#还很陌生,所以任何帮助都将是宝贵的,这个问题困扰了我好一阵子:(


是WinForms还是WPF? - outcoldman
窗体应用程序 - Someone
4个回答

28

await 关键字与 Task.Delay 结合使用使得这个问题变得微不足道。

public async Task Foo()
{
    await Task.Delay(2000);
    txtConsole.AppendText("Waiting...");
    DoStuff();
}

4
你确实不必这样做。你可以使用Task.Delay(2000).ContinueWith(t=>DoStuff(), ..., Task.Factory.FromCurrentSynchronizationContext());来代替,这正是await最终会重构为的内容。 - Servy
@Servy,您会如何在.Net4.0中处理这个问题? - Arvo Bowen
@ArvoBowen 你应该使用ContinueWith而不是await。如果你想要良好的错误处理语义,那么需要做更多的工作,但除了处理错误之外,你只需将其余代码放在继续执行中,这并不难。 - Servy
@Servy 那我想对于我来说,代码应该是 Task.Factory.StartNew(() => DoStuffStart(), CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default).ContinueWith((t) => DoStuffFinished(t.Result)); ;) - Arvo Bowen
1
@IamDOM 代码都在UI线程中运行,因此没有任何并发运行的内容。是的,在“DoStuff”调用之间可能会运行其他UI事件。它需要编写以支持这一点。我从问题中看不出任何迹象表明它不是这样。也没有真正的替代方案。 - Servy
显示剩余3条评论

2

尝试使用DispatcherTimer。它是一个非常方便的对象,可以完成所有委托到UI线程的工作。

例如:

private DispatcherTimer _dtTimer = null;

public Constructor1(){
  _dtTimer = new DispatcherTimer();
  _dtTimer.Tick += new System.EventHandler(HandleTick);
  _dtTimer.Interval = new TimeSpan(0, 0, 0, 2); //Timespan of 2 seconds
  _dtTimer.Start();
}

private void HandleTick(object sender, System.EventArgs e) {
  _uiTextBlock.Text = "Timer ticked!";
}

-1
计时器在这种情况下应该可以正常工作,除非您在其处理程序中放置了Thread.Sleep或处理程序本身需要太长时间才能完成。
您没有指定使用的UI框架或.Net版本,但对于最新的.Net,您可以使用async/await。这样,当您的代码等待后台任务时,UI不会被冻结。
void async MyMethod()
{  
    var result = await Task.Run(() => long_running_code);
}

-1
DateTime Tthen = DateTime.Now;
            do
            {
                Application.DoEvents();
            } while (Tthen.AddSeconds(5) > DateTime.Now);    

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接