是否可以检测您是否处于异步方法的同步端?

时间:2014-04-07 22:10:32

标签: c# asp.net async-await

我正在尝试为Web应用程序开发一个上下文系统,它将沿着逻辑控制流传播数据。这类似于描述enter link description here的AsyncLocal堆栈。

最初,我只是使用LogicalCallContext来执行此操作,但这会遇到ASP.NET线程敏捷性问题。为了解决这个问题,我实现了一个混合系统,它使用逻辑调用上下文和HttpContext.Items。使用这个系统,我们保持两个上下文同步(假设它们都可用),并信任逻辑调用上下文,除非它丢失并且HttpContext.Items中有一些内容。

这几乎适用于所有情况,但是在异步方法的前半部分会遇到麻烦,该方法是从同步方法调用的,我们在请求线程上但在不同的逻辑调用上下文中。这是一个例子:

// in BeginRequest
MyContext.Push("BeginRequest");

public ActionResult SomeAction() 
{
    // sometimes Asp.NET does a thread switch between begin request and the action
    // in that case, we have:
    // Logical: null
    // HttpContext:  "BeginRequest"

    var result = this.DoSomethingAsync().Result;

    // Here we have
    // Logical: null
    // THIS IS WRONG: the logical context was correctly restored by async magic, but we
    // corrupted the HttpContext. Since we lost the logical call context, we can't use that
    // HttpContext: "DoSomethingAsync" -> "BeginRequest"
}

private async Task DoSomethingAsync()
{
    // right now we're on the request thread, so we still have HttpContext but
    // because we have a logical call context 
    // I would like to detect when the code is in THIS STATE
    MyContext.Push("DoSomethingAsync");

    // Here we have
    // Logical: "DoSomethingAsync" -> "BeginRequest"
    // HttpContext: "DoSomethingAsync" -> "BeginRequest"

    // because this method does ConfigureAwait(false), on the other side of await
    // you won't have the context
    await ComputeSomethingAsync().ConfigureAwait(false);

    // Here we have
    // Logical: "DoSomethingAsync" -> "BeginRequest"
    // HttpContext: null    

    MyContext.Pop();

    // Here we have
    // Logical: "BeginRequest"
    // HttpContext: null    
}

有没有办法检测到这种状态?是否有另一种方法可以在ASP.NET / .NET 4.5中获得一致的逻辑上下文流?

0 个答案:

没有答案
相关问题