为什么等待寒冷任务不会抛出 [英] Why awaiting cold Task does not throw

查看:81
本文介绍了为什么等待寒冷任务不会抛出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是尝试,看看当一个冷的任务(即一工作其中尚未启动)是等待会发生什么。令我惊讶的code只是挂永远的Finsihed 的从不打印。我预计会抛出异常。

I was just experimenting to see what happens when a cold task (i.e. a Task which hasn't been started) is awaited. To my surprise the code just hung forever and "Finsihed" is never printed. I would expect that an exception is thrown.

public async Task Test1()
{
    var task = new Task(() => Thread.Sleep(1000));
    //task.Start();
    await task;
}

void Main()
{
    Test1().Wait();
    Console.WriteLine("Finished");
}

然后我虽然也许可以将任务从另一个线程开始,所以我改变了code为:

Then I though perhaps the task can be started from another thread, so I changed the code to:

public async Task Test1()
{
    var task = new Task(() => Thread.Sleep(1000));
    //task.Start();
    await task;

    Console.WriteLine("Test1 Finished");
}

void Main()
{
    var task1 = Test1();

    Task.Run(() => 
    {
        Task.Delay(5000);   
        task1.Start();
    });

    task1.Wait();
    Console.WriteLine("Finished");
}

但它仍然受阻于 task1.Wait()。有谁知道是否有方法来启动一个寒冷的任务,它已经被期待已久的后?

But it is still blocked at task1.Wait(). Does anyone know if there is way to start a cold task after it has being awaited?

否则,它似乎还有在能够等待寒冷的任务是没有意义的,所以也许任务应该要么等待时或异常应该抛出启动。

Otherwise it seems there is no point in being able to await a cold task, so perhaps the task should either be started when awaited or an exception should be thrown.

更新

我在等待了错误的任务,即通过测试1 ,而不是里面一个newed返回外任务。通过@乔恩飞碟双向提到的InvalidOperationException异常被抛出在 Task.Run 然而,由于没有观察到所产生的任务,异常被抛出不能在主线程。把一个的try / catch Task.Run 或致电等待()结果 Task.Run 任务丢给主控台线程上的异常。

I was awaiting the wrong task, i.e. the outer task returned by Test1 rather than the one newed inside it. The InvalidOperationException mentioned by @Jon Skeet was being thrown inside Task.Run however because the resulting task was not observed, the exception was not thrown on the main thread. Putting a try/catch inside Task.Run or calling Wait() or Result on the task returned by Task.Run threw the exception on the main console thread.

推荐答案

您正试图通过启动异步方法返回的任务 - 的的不是你开始御寒任务。事实上,如果你添加一些诊断你的 Task.Run 电话,你会看到一个异常被抛出:

You're trying to start the task returned by the async method - that isn't the cold task that you started out with. Indeed, if you add some diagnostics to your Task.Run call, you'll see that an exception is thrown:

System.InvalidOperationException:开始可能不会被要求承诺式的任务

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

下面是显示什么,我觉得你真的想做一个例子:

Here's an example showing what I think you were really trying to do:

using System;
using System.Threading;
using System.Threading.Tasks;

public class Test
{
    static void Main(string[] args)
    {
        // Not using Task.Delay! That would be pointless
        Task t1 = new Task(() => Thread.Sleep(1000));
        Task t2 = Await(t1);
        Console.WriteLine(t2.Status);
        Console.WriteLine("Starting original task");
        t1.Start(); 
        Console.WriteLine(t2.Status);
        t2.Wait();
        Console.WriteLine(t2.Status);        
    }

    static async Task Await(Task task)
    {
        Console.WriteLine("Beginning awaiting");
        await task;
        Console.WriteLine("Finished awaiting");        
    }
}

请注意使用 Thread.sleep代码而不是 Task.Delay ;除非你使用 Task.Delay 的结果,它基本上什么都不做。使用 Thread.sleep代码是模拟实际工作中的其他任务来完成。

Note the use of Thread.Sleep instead of Task.Delay; unless you're using the result of Task.Delay, it basically does nothing. Using Thread.Sleep is emulating real work to be done in the other task.

至于为什么等待一个尚未启动的任务不会抛出异常 - 我认为这是合理的,是诚实的。它允许像上述情况是有效的,这可能在某些情况下,使生活更轻松。 (你可以启动它们,例如之前创造了很多的任务 - 你可能要开始等着你开始之前他们完成)

As for why awaiting an unstarted task doesn't throw an exception - I think that's reasonable, to be honest. It allows for situations like the above to be valid, which may in some cases make life easier. (You may create a lot of tasks before starting them, for example - and you may want to start waiting for them to finish before you start them.)

这篇关于为什么等待寒冷任务不会抛出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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