我正在创建一个简单的 wpf 桌面应用程序。 UI 只有一个按钮和 .cs 文件中的代码,例如。
private void Button_Click_2(object sender, RoutedEventArgs e)
{
FunctionA();
}
public void FunctionA()
{
Task.Delay(5000).Start();
MessageBox.Show("Waiting Complete");
}
但出人意料的线路Task.Delay(5000).Start();
正在扔一个InvalidOperationException
:
不能对承诺式任务调用 Start。
任何人都可以帮助为什么会这样吗?
您收到该错误是因为Task
在把任务交给你之前,班级已经开始了任务。你应该只打电话Start
在通过调用其构造函数创建的任务上,您甚至不应该这样做,除非您有令人信服的理由在创建任务时不启动该任务;如果你希望它立即开始你应该使用Task.Run
or Task.Factory.StartNew
创建并开始一个新的Task
.
所以,现在我们知道要摆脱那个讨厌的东西Start
。您将运行代码并发现消息框立即显示,而不是 5 秒后显示,这是怎么回事?
Well, Task.Delay
只是给你一个5秒内完成的任务。它不会停止线程的执行 5 秒。您想要做的是在该任务完成后执行一些代码。就是这样ContinueWith
是为了.它允许您在给定任务完成后运行一些代码:
public void FunctionA()
{
Task.Delay(5000)
.ContinueWith(t =>
{
MessageBox.Show("Waiting Complete");
});
}
这将按预期运行。
我们还可以利用 C# 5.0await
关键字可以更轻松地添加延续:
public async Task FunctionA()
{
await Task.Delay(5000);
MessageBox.Show("Waiting Complete");
}
虽然对这里发生的事情的完整解释超出了这个问题的范围,但最终结果是一种行为与之前的方法非常相似的方法;调用该方法 5 秒后,它将显示一个消息框,但在这两种情况下,该方法本身将[几乎]立即返回。也就是说,await
非常强大,允许我们编写看起来简单明了的方法,但使用它来编写会更加困难和混乱ContinueWith
直接地。它还极大地简化了错误处理,删除了大量样板代码。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)