D J*_*D J 104 c# .net-4.0 c#-4.0
我正在创建一个简单的wpf桌面应用程序.UI只有一个按钮和.cs文件中的代码.
private void Button_Click_2(object sender, RoutedEventArgs e)
{
FunctionA();
}
public void FunctionA()
{
Task.Delay(5000).Start();
MessageBox.Show("Waiting Complete");
}
Run Code Online (Sandbox Code Playgroud)
但令人惊讶的Task.Delay(5000).Start();
是,线路投掷了InvalidOperationException
:
可能不会在promise样式的任务上调用Start.
任何人都能帮助为什么会这样吗?
Ser*_*rvy 163
您收到该错误,因为Task
该类已经在将该任务提供给您之前已经启动了该任务.你应该只调用Start
你通过调用它的构造函数创建的任务,你甚至不应该这样做,除非你有一个令人信服的理由在创建它时不启动任务; 如果你想立即开始,你应该使用Task.Run
或Task.Factory.StartNew
创建和开始新的Task
.
所以,现在我们知道要摆脱那种麻烦Start
.您将运行您的代码并发现消息框立即显示,而不是5秒后,该怎么办?
好吧,Task.Delay
只给你一个将在5秒内完成的任务.它不会停止执行该线程5秒钟.你想要做的是拥有一些在该任务完成后执行的代码.这ContinueWith
是为了什么.它允许您在完成给定任务后运行一些代码:
public void FunctionA()
{
Task.Delay(5000)
.ContinueWith(t =>
{
MessageBox.Show("Waiting Complete");
});
}
Run Code Online (Sandbox Code Playgroud)
这将按预期运行.
我们还可以利用C#5.0的await
关键字更轻松地添加延续:
public async Task FunctionA()
{
await Task.Delay(5000);
MessageBox.Show("Waiting Complete");
}
Run Code Online (Sandbox Code Playgroud)
虽然对此处发生的事情的完整解释超出了本问题的范围,但最终结果是一种行为与前一种方法非常相似; 它会在你调用方法后5秒显示一个消息框,但在这两种情况下,方法本身将立即返回[几乎].也就是说,await
它非常强大,并且允许我们编写看似简单明了的方法,但ContinueWith
直接使用它会变得更加困难和混乱.它还大大简化了错误处理的处理,取出了大量的样板代码.