Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 不能对承诺式任务调用Start。例外就要来了_C#_C# 4.0_.net 4.0 - Fatal编程技术网

C# 不能对承诺式任务调用Start。例外就要来了

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

我正在创建一个简单的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


有人能解释为什么会这样吗?

您会遇到这个错误,因为
任务
类在将任务交给您之前已经启动了任务。您应该只对通过调用构造函数创建的任务调用
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
编写方法会更加困难和混乱。它还极大地简化了错误处理,省去了大量样板代码