asp.net - 从 Application_BeginRequest() 中设置后,AsyncLocal 值为 Null

标签 asp.net .net asp.net-mvc asynchronous

在以下示例中,我将值设置为 AsyncLocal<string>我的变量HttpApplication Application_BeginRequest() 中的子类(即 Global.asax) :

public class Global : System.Web.HttpApplication
{
    public static AsyncLocal<string> AsyncLocalState = new AsyncLocal<string>();

    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        AsyncLocalState.Value = HttpContext.Current.Request.Path;
    }

    protected void Application_AuthenticateRequest(object sender, EventArgs e)
    {
        var path = AsyncLocalState.Value;
    }

    protected void Application_EndRequest(object sender, EventArgs e)
    {
        var path = AsyncLocalState.Value;
    }
}

稍后,我将尝试访问此 AsyncLocal 的值来自处理程序内的变量,例如 MVC 操作方法,甚至只是一个简单的 IHttpHandler .

如果我发送一个足够大的请求(例如,一个包含超过 15KB 数据的 POST——请求越大,越容易观察),AsyncLocalState 的值很有可能从处理程序访问时为 NULL ,即使它设置为 BeginRequest

这可以从全新的 ASP.NET 项目中重现,无需加载任何其他库/模块/处理程序。

这是一个错误吗?或者也许我做错了什么?或者 ASP.NET 对此来说太不稳定了吗?

补充说明:如果我改为使用 CallContext.LogicalGetData ,则会观察到完全相同的行为/CallContext.LogicalSetData .

平台:ASP.NET、.NET 4.6.2、Windows 7

更新:在尝试深入研究后,我发现了很多引用资料,但没有任何权威说明 ExecutionContext 不会在 ASP.NET 管道事件之间流动(除了什么时候?)。两者都是AsyncLocal逻辑调用上下文基于 ExecutionContext .

最佳答案

最接近权威答案的是 this comment通过 David Fowl在 GitHub 上。

如果 ASP.NET 管道事件不同步执行,ExecutionContext 不会在这些事件之间流动。因此,不要使用 AsyncLocal 或逻辑 CallContext 来持久化状态;使用HttpContext.Items

更新:.NET 4.7.1 添加了一个新的回调方法 HttpApplication.OnExecuteRequestStep,根据文档,该方法“为 ASP.NET 管道提供了可扩展性,使开发人员可以轻松实现环境上下文场景中的功能并构建关心 ASP.NET 执行流(例如跟踪、分析、诊断和事务)的库。"

这正是恢复 ASP.NET 管道事件之间的 AsyncLocal 状态或逻辑 CallContext 所需要的。

关于asp.net - 从 Application_BeginRequest() 中设置后,AsyncLocal 值为 Null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43391498/

相关文章:

asp.net - 创建ASP.NET成员资格提供程序用户的脚本

c# - ValidationSummary 不显示错误

c# - 如何知道 GridView 的 ItemTemplate 中服务器控件的 id?

jQuery 这真的应该被视为硬编码值吗?

c# - Response.redirect 不在 c# 中重定向

c# - 如何在 WebForms 项目中启用 MVC?

asp.net - ASMX Web 服务 - 返回具有属性的用户定义的类

.net - 在完整框架 4.7 项目中添加对 .NET Core 2.0 DLL 的引用

c# - Windows 服务如何在引发计时器事件时启动进程?

c# - 优化具有多个条件的嵌套 where 子句的最佳方法是什么?