Почему HttpContext.Current не является нулевым в async / await с ConfigureAwait - PullRequest
0 голосов
/ 09 марта 2019

У меня есть библиотека асинхронная функция, вызываемая из контроллера.Я ожидал, что HttpContext.Current будет нулевым после ожидания везде с ConfigureAwait (false) везде, но в контроллере он не равен нулю.Может кто-нибудь объяснить, почему?

//in libraby
public class MyClass
{
    public async Task WaitAsync()
    {
        await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false);

        var httpContext = System.Web.HttpContext.Current; // null, OK
    }
}

public class HomeController : Controller
{
    public async Task<ActionResult> Index()
    {
        var class1 = new MyClass();
        await class1.WaitAsync();

        var httpContext = System.Web.HttpContext.Current; // not null, WHY???

        return View("Index");
    }
}

1 Ответ

1 голос
/ 09 марта 2019

Хотя это намного сложнее, вы можете изобразить await как ContinueWith.Так, если вы напишите, например:

DoSomeStuff();
await WaitAsync()
DoMoreStuff();

Он будет переписан следующим образом:

DoSomeStuff();
WaitAsync().ContinueWith(_ => DoMoreStuff());

.ConfigureAwait устанавливает контекст, в котором будет выполняться продолжение.При ConfigureAwait(true) (по умолчанию) продолжение будет выполняться в том же контексте, что и вызывающая сторона.При ConfigureAwait(false) продолжение будет выполняться в инвариантном контексте по умолчанию в пуле потоков.С нашим предыдущим упрощением давайте представим, что ConfigureAwait(true) будет переписано в ContinueWithSameContext и ConfigureAwait(false) в ContinueWithThreadPool.

Что теперь произойдет, если у нас есть вложенные методы?Например, ваш код:

public async Task WaitAsync()
{
    await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false);

    var httpContext = System.Web.HttpContext.Current; // null, OK
}

public async Task<ActionResult> Index()
{
    var class1 = new MyClass();
    await class1.WaitAsync();

    var httpContext = System.Web.HttpContext.Current; // not null, WHY???

    return View("Index");
}

Это тоже переписано:

public Task WaitAsync()
{
    return Task.Delay(TimeSpan.FromSeconds(1))
        .ContinueWithThreadPool(_ => 
        {
            var httpContext = System.Web.HttpContext.Current; // null, OK
        });
}        

public Task<ActionResult> Index()
{
    var class1 = new MyClass();
    return class1.WaitAsync().ContinueWithSameContext(_ =>
    {
        var httpContext = System.Web.HttpContext.Current; // not null, WHY???

        return View("Index");
    }
}

Переписав таким образом, вы увидите, что продолжение WaitAsync будет работать в том же контексте, что и Task<ActionResult> Index(), объясняя, почему HttpContext не равен нулю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...