首页 > 解决方案 > 如果在阻塞代码下方一直使用 .ConfigureAwait(false) ,阻塞异步调用之后的代码是否会在相同的上下文中继续?

问题描述

首先,我只想说我知道你应该使用await/async整个堆栈,而不是阻塞异步代码。我知道这会导致死锁。

可以说我有这个代码:

public void SomeMethod()
{
    var result = GetData().Result;

    var context2 = HttpContext.Current;
}

public async Task<string> GetData()
{
    // ... do stuff

    var result = await new HttpClient().GetStringAsync("https://stackoverflow.com").ConfigureAwait(false);

    var context1 = HttpContext.Current;

    // ... process result

    return processedResult; // processedResult could be whatever
}

在这种情况下,代码必须等待 HTTP 请求完成。这context1将是null因为代码在请求完成后在任意线程上运行。这是因为.ConfigureAwait(false)调用,它必须等待请求完成。

从研究和测试来看,它看起来context2总是有一个价值,永远不会null。从我的推理来看,这是合乎逻辑的。, .Wait(),.Result.GetAwaiter().GetResult()将阻塞线程,然后继续它。但是,我还没有找到明确说明这一点的文档。也许我在寻找错误的地方,或者它太基本以至于没有真正写在任何地方。我的意思是,为什么它会突然改变线程?我想我想知道,因为代码.ConfigureAwait(false)在任何其他线程上运行之后。有没有context2可能null

标签: c#async-await

解决方案


该行将var result = GetData().Result;导致当前线程被阻塞,直到异步操作GetData()完成。当线程恢复时,HttpContext.Current将具有与以前相同的值,除非注释表示的代码// ... do stuff已将其明确设置为null

HttpContext.Current = null;

推荐阅读