C# 异步操作后的HttpContext.Current.Items

C# 异步操作后的HttpContext.Current.Items,c#,asp.net,asp.net-web-api,.net-4.5,async-await,C#,Asp.net,Asp.net Web Api,.net 4.5,Async Await,考虑以下ASP.NET Web API委派处理程序: 公共类MyHandler:DelegatingHandler { 受保护的异步重写任务SendAsync(HttpRequestMessage请求,System.Threading.CancellationToken CancellationToken) { var guid=guid.NewGuid(); HttpContext.Current.Items[“foo”]=guid; //异步操作 var result=await base

考虑以下ASP.NET Web API委派处理程序:

公共类MyHandler:DelegatingHandler
{
受保护的异步重写任务SendAsync(HttpRequestMessage请求,System.Threading.CancellationToken CancellationToken)
{
var guid=guid.NewGuid();
HttpContext.Current.Items[“foo”]=guid;
//异步操作
var result=await base.sendaync(请求、取消令牌);
//这一点上的所有代码都不需要在启动处理程序的同一线程上运行
var restoredGuid=(Guid)HttpContext.Current.Items[“foo”];
//这是真的吗
var areTheSame=guid==restoredGuid;
返回结果;
}
}
上面的例子是在一个委托处理程序中,我试图解决的问题同样适用于控制器、业务对象等

我最终尝试为每个HTTP请求提供不同对象之间的一些简单内存共享状态

据我所知,在异步操作期间,最初运行该操作的ASP.NET线程将返回到线程池,异步操作完成后,可能会使用另一个线程来完成请求

这是否会影响
HttpContext.Current.Items
集合? 请求恢复时,
Items
集合中的项目是否保证存在

  • 我知道,使用
    HttpContext.Current
    通常会受到 我完全同意这些天更广泛的社区的原因 具有我只是在帮别人摆脱困境

  • 将此数据存储在
    Request.Items
    集合中不适合解决此问题,因为我的同事由于一些糟糕的设计决策而需要静态数据


  • 非常感谢

    长话短说,通常应该如此。除非您使用的是
    ConfigureAwait(false)
    ,这可能会对continuation不在上下文中流动产生副作用

    或者,尝试在应用程序中添加此设置

    <appSettings>
        <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
    </appSettings>
    
    
    
    更新 注意!! 起初我把它放错了。但它必须是真的,这样上下文才会流动

    据我所知,在异步操作期间,最初运行该操作的ASP.NET线程将返回到线程池,异步操作完成后,可能会使用另一个线程来完成请求

    这是正确的。但是让我们在ASP.NET上讨论一下
    async

    async
    需要.NET 4.5。此外,ASP.NET 4.5在服务器端引入了“怪癖模式”,您必须关闭
    SynchronizationContext
    怪癖。您可以通过将
    httpRuntime.targetFramework
    设置为
    4.5
    ,或者使用
    appSettings
    aspnet:UseTaskFriendlySynchronizationContext
    true
    来实现这一点

    如果web.config没有这些条目之一,则
    async
    的行为未定义。有关更多详细信息,请参阅。我建议使用
    targetFramework
    设置并修复出现的任何问题

    这是否会影响HttpContext.Current.Items集合?当请求恢复时,是否保证Items集合中的某个项目在那里

    AspNetSynchronizationContext
    wait
    点之间保留当前请求上下文。这包括
    HttpContext.Current
    (其中包括
    用户
    等)

    另一种可能是
    CallContext.Logical[Get | Set]Data
    ,它也会在
    wait
    点之间流动。如果您不希望代码依赖于
    HttpContext
    ,但开销稍大,则此选项非常有用


    几周前,我在那次会议上就;您可能会发现这些幻灯片很有帮助,特别是那些涉及上下文和线程本地状态的幻灯片。

    这可能会有帮助:这是:嗨,Jason,这些问题;虽然相似;这些都不是一回事。谢谢。啊,好的:)不用担心。
    HttpContext
    将被保留,但延续线程可能不同。将管理上下文。谢谢Stephen,反应很好。
    <appSettings>
        <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
    </appSettings>