ConfigureAwait(false)不能按预期使HttpContext为NULL [英] ConfigureAwait(false) not making HttpContext NULL as expected

查看:168
本文介绍了ConfigureAwait(false)不能按预期使HttpContext为NULL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用async/await时,为避免死锁,建议一直使用ConfigureAwait(false)直到最后一层.我知道使用ConfigureAwait(false)也会使当前的HttpContext为空. 文章

When using async/await, to avoid deadlocks, it is recommended to use ConfigureAwait(false) to all the way down to the last layer. I understand that using ConfigureAwait(false) will also make the current HttpContext null. Article

下面是示例代码,目的只是为了理解为什么ConfigureAwait(false)在期望时没有使HttpContext为NULL,而在没有期望时没有使HttpContext为NULL.

Below is the sample code just to understand why ConfigureAwait(false) is not making HttpContext NULL when expected, and making it NULL when it is NOT expected.

控制器

public class MyController : Controller
{
    private readonly MyService _service = new MyService();
    private readonly MyMapper _mapper = new MyMapper();        


    public async Task<ActionResult> DoSomething()
    {
        var data = await _service.GetData().ConfigureAwait(false);

        // EXPECTED: Below, HttpContext should NOT NULL
        // ACTUAL: HttpContext is NOT NULL as expected
        if (HttpContext == null)
        {
            throw new ArgumentNullException("context");
        }

        var model = _mapper.Map(data);

        return View(model);
    }
}

一种服务,用于异步调用GetData的数据源

public class MyService
{
    public async Task<string> GetData()
    {
        // EXPECTED: HttpContext should be NULL here since we are calling 
        //this method from the Controller with ConfigureAwait(false)     

        // ACTUAL: HttpContext is NOT NULL, WHY?
        if(HttpContext.Current == null)
        {
            throw new ArgumentNullException("context");
        }

        using (var client = new HttpClient())
        {
            var response = await client.GetAsync("http://url").ConfigureAwait(false);
            response.EnsureSuccessStatusCode();
            return await response.Content.ReadAsStringAsync().ConfigureAwait(false);
        }
    }
}

映射器类将数据映射到模型

public class MyMapper
{
    public MyModel Map(string data)
    {
        // EXPECTED:  HttpContext should NOT NULL here since async call is already done.
        // ACTUAL: HttpContext is NULL here. WHY?
        if (HttpContext.Current == null)
        {
            throw new ArgumentNullException("context");
        };

        return new MyModel()
        {
            Message = data
        };
    }
}

MyService内HttpContext预期为NULL,在MyMapper内HttpContext预期为非NULL,但这不是事实.请在MyServiceMyMapper

The HttpContext is expected to be NULL inside MyService and expected to be NOT NULL inside MyMapper, but that is not the case. Please see my inline comments inside MyService and MyMapper

推荐答案

您将其倒退. HttpContext.Current在上下文切换之后 之前为空,而不是之前.

You have it backwards. HttpContext.Current will be null after the context switch, not before.

所以:

// ACTUAL: HttpContext is NOT NULL, WHY?
if(HttpContext.Current == null)
{
    throw new ArgumentNullException("context");
}

不,期望不是null,因为到目前为止没有任何await(父级await不适用).

No, it is expected to be not null since there hasn't been any await so far (the parent await does not apply).

// EXPECTED:  HttpContext should NOT NULL here since async call is already done.
// ACTUAL: HttpContext is NULL here. WHY?
if (HttpContext.Current == null)

切换发生在此行之后

var response = await client.GetAsync("http://url").ConfigureAwait(false);

所以应该是null.

这篇关于ConfigureAwait(false)不能按预期使HttpContext为NULL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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