开始可能无法在承诺式的任务调用。例外来了 [英] Start may not be called on a promise-style task. exception is coming

查看:2310
本文介绍了开始可能无法在承诺式的任务调用。例外来了的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建一个简单的WPF桌面应用程序。 UI刚才一个按钮,代码.cs文件等。

I am creating a simple wpf desktop application. UI have just a button and code in .cs file like.

private void Button_Click_2(object sender, RoutedEventArgs e)
{
    FunctionA();
}

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



但令人意外的行 Task.Delay(5000)。启动(); 抛出一个出现InvalidOperationException

开始可能无法在承诺式的任务调用。

Start may not be called on a promise-style task.

任何一个可以帮助它为什么是这样呢?

Can any one help why it is like this?

推荐答案

您获得的是错误,因为工作类它给你之前已经开始的任务。你应该永远只能叫开始在您通过调用其构造函数创建一个任务,你应该甚至不应该做,除非你有一个令人信服的理由,不能启动时任务你创建它;如果你想让它马上开始你应该使用 Task.Run Task.Factory.StartNew 双方建立和启动一个新的工作

You are getting that error because the Task class already started the task before giving it to you. You should only ever call Start on a task that you create by calling its constructor, and you shouldn't even do that unless you have a compelling reason to not start the task when you create it; if you want it started right away you should use Task.Run or Task.Factory.StartNew to both create and start a new Task.

所以,现在我们知道刚刚摆脱讨厌的开始。你会遇到你的代码,并发现,消息框将被立即显示,而不是5秒钟后,如何处理这事?

So, now we know to just get rid of that pesky Start. You'll run your code and find that the message box is shown right away, not 5 seconds later, what's up with that?

好吧, Task.Delay 只是给你,将在5秒内完成的任务。它并不5秒停止线程的执行。你想要做的是有一个任务完成后的执行一些代码。这就是 ContinueWith 是。它可以让你运行一些代码给定的任务完成后:

Well, Task.Delay just gives you a task that will be completed in 5 seconds. It doesn't stop execution of the thread for 5 seconds. What you want to do is have some code that's executed after that task finishes. That's what ContinueWith is for. It lets you run some code after a given task is done:

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

这会像预期的那样。

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

We could also leverage C# 5.0's await keyword to add continuations more easily:

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



虽然这是怎么回事上的完整解释超出了这个问题的范围,最终的结果是,表现非常类似于前述方法的方法;它会显示一个消息框5秒钟,然后再调用该方法后,但该方法本身将返回[近]就在这两种情况下离开。这就是说,等待是非常强大的,并且允许我们编写似乎简单而直接的方法,但是这将是非常困难和混乱使用写 ContinueWith 直接。这也极大简化处理错误处理,采取了很多的样板代码。

While a full explanation of what's going on here is beyond the scope of this question, the end result is a method that behaves very similar to the previous method; it will show a message box 5 seconds after you call the method, but the method itself will return [almost] right away in both cases. That said, await is very powerful, and allows us to write methods that seem simple and straightforward, but that would be much harder and messier to write using ContinueWith directly. It also greatly simplifies dealing with error handling, taking out a lot of boilerplate code.

这篇关于开始可能无法在承诺式的任务调用。例外来了的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆