会发生什么异步code任务时,不等待 [英] What happens with asynchronous code when Tasks are not awaited

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

问题描述

由于code类似于

Task.Run(() =>
{
    using (var client = new HttpClient())
    {
        var responseTask = client.GetAsync(urlToInvoke);
    }
});

在这样的情况下,似乎 GetAsync 并没有实际操作。是任务取消之前完成,或者什么是真正回事?

In a situation like this, it appears that GetAsync does not actually operate. Is the task canceled prior to completion or what is actually going on here?

现在,如果你改变的事情略有并插入

Now if you change things slightly and insert

Task.Run(() =>
{
    using (var client = new HttpClient())
    {
        var responseTask = client.GetAsync(urlToInvoke);

        Task.Delay(5000).Wait()
    }
});

GetAsync 没有完全执行。这里发生了什么?为 Task.Delay affinitizing本身相同任务就是里面的 responseTask 最终使这相当于 responseTask.Wait()

GetAsync does execute completely. What is going on here? Is Task.Delay affinitizing itself to the same Task that is inside responseTask ultimately making this equivalent to responseTask.Wait()?

推荐答案

您所想的是不正确的。这里是正在发生的事情在类中的伪版本。

You are thinking of it incorrectly. Here is pseudo version of what is happening inside the class.

class HttpClient : IDisposeable
{
    private CancelationTokenSource _disposeCts;

    public HttpClient()
    {
        _disposeCts = new CancelationTokenSource();
    }

    public Task<HttpResponseMessage> GetAsync(string url)
    {
        return GetAsync(url, CancellationToken.None);
    }

    public async Task<HttpResponseMessage> GetAsync(string url, CancelationToken token)
    {
        var combinedCts = CancellationTokenSource.CreateLinkedTokenSource(token, _disposeCts.Token);
        var tokenToUse = combinedCts.Token;


        //... snipped code

        //Some spot where it would good to check if we have canceled yet.
        tokenToUse.ThrowIfCancellationRequested();

        //... More snipped code;

        return result;
    }

    public void Dispose()
    {
        _disposeCts.Cancel();
    }

    //... A whole bunch of other stuff.
}

重要的是要看到的是,当你退出使用 A座内取消令牌将被取消。

The important thing to see is when you exit the using block a internal cancelation token is canceled.

在你的第一个例子中的任务还没有完成呢等等 tokenToUse 现在会抛出,如果 ThrowIfCancellationRequested()被称为。

In your first example the task had not finished yet so tokenToUse would now throw if ThrowIfCancellationRequested() was called.

在第二个例子中,任务已经完成了,以便消除内部令牌的行为对返回,由于它已经达到完成状态的任务没有影响。

In your second example the task had already finished so the act of canceling the internal token had no effect on the task that was returned due to it already reaching the completed state.

这就像问为什么这会导致任务被取消。

It is like asking why this causes the task to be canceled.

using (var client = new HttpClient())
{
    var cts = new CancellationTokenSource()
    var responseTask = client.GetAsync(urlToInvoke, cts.Token);

    cts.Cancel();
}

但这并不

using (var client = new HttpClient())
{
    var cts = new CancellationTokenSource()
    var responseTask = client.GetAsync(urlToInvoke, cts.Token);

    Task.Delay(5000).Wait()
    cts.Cancel();
}

这篇关于会发生什么异步code任务时,不等待的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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