gpt4 book ai didi

c# - Start 可能不会在 promise 风格的任务上被调用。异常(exception)来了

转载 作者:IT王子 更新时间:2023-10-29 03:35:36 26 4
gpt4 key购买 nike

我正在创建一个简单的 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 may not be called on a promise-style task.

谁能帮忙解释为什么会这样?

最佳答案

您收到该错误是因为 Task 类在将任务交给您之前已经启动了该任务。您应该只在通过调用其构造函数创建的任务上调用 Start,您甚至不应该这样做,除非您有令人信服的理由在创建任务时不启动该任务;如果您希望它立即启动,您应该使用 Task.RunTask.Factory.StartNew 创建并启动一个新的 Task

所以,现在我们知道要摆脱那个讨厌的 Start 了。您将运行您的代码并发现消息框立即显示,而不是 5 秒后,这是怎么回事?

好吧,Task.Delay 只是为您提供了一个将在 5 秒内完成的任务。它不会停止执行线程 5 秒。您想要做的是在该任务完成后执行一些代码。这就是 ContinueWith 的用途。它允许您在完成给定任务后运行一些代码:

public void FunctionA()
{
Task.Delay(5000)
.ContinueWith(t =>
{
MessageBox.Show("Waiting Complete");
});
}

这将按预期运行。

我们还可以利用 C# 5.0 的 await 关键字更轻松地添加延续:

public async Task FunctionA()
{
await Task.Delay(5000);
MessageBox.Show("Waiting Complete");
}

虽然对这里发生的事情的完整解释超出了这个问题的范围,但最终结果是一种行为与之前的方法非常相似的方法;它会在您调用该方法 5 秒后显示一个消息框,但在这两种情况下,该方法本身都会 [几乎] 立即返回。也就是说,await 非常强大,它允许我们编写看似简单直接的方法,但如果直接使用 ContinueWith 来编写,那将更加困难和困惑。它还极大地简化了错误处理,去除了大量样板代码。

关于c# - Start 可能不会在 promise 风格的任务上被调用。异常(exception)来了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14230372/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com