C# 不能对承诺式任务调用Start。例外就要来了
我正在创建一个简单的wpf桌面应用程序。UI只有一个按钮和.cs文件中的代码C# 不能对承诺式任务调用Start。例外就要来了,c#,c#-4.0,.net-4.0,C#,C# 4.0,.net 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"); } 但令人惊讶的是,行Task.Delay(5000.St
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
有人能解释为什么会这样吗?您会遇到这个错误,因为
任务
类在将任务交给您之前已经启动了任务。您应该只对通过调用构造函数创建的任务调用Start
,并且您甚至不应该这样做,除非您有令人信服的理由在创建任务时不启动它;如果要立即启动,应使用Task.Run
或Task.Factory.StartNew
创建和启动新的任务
所以,现在我们知道要摆脱那些讨厌的Start
。您将运行代码,发现消息框立即显示,而不是5秒后,这是怎么回事
好吧,Task.Delay
只会给你一个5秒钟就能完成的任务。它不会在5秒钟内停止线程的执行。您要做的是在任务完成后执行一些代码。这就是ContinueWith
的作用。它允许您在完成给定任务后运行一些代码:
public void FunctionA()
{
Task.Delay(5000)
.ContinueWith(t =>
{
MessageBox.Show("Waiting Complete");
});
}
这将按预期进行
我们还可以利用C#5.0的wait
关键字更轻松地添加延续:
public async Task FunctionA()
{
await Task.Delay(5000);
MessageBox.Show("Waiting Complete");
}
虽然对这里发生的事情的完整解释超出了这个问题的范围,但最终的结果是一种行为与前一种方法非常相似的方法;在调用该方法5秒后,它将显示一个消息框,但在这两种情况下,该方法本身都会立即返回。这就是说,await
功能非常强大,它允许我们编写看似简单直接的方法,但直接使用ContinueWith
编写方法会更加困难和混乱。它还极大地简化了错误处理,省去了大量样板代码