從 Application_BeginRequest() 中設置後,AsyncLocal 值為 Null
在以下範例中,我從內部為我的子類(即 Global.asax)
AsyncLocal<string>上的變數設置一個值:HttpApplication``Application_BeginRequest()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 上
**更新:**在嘗試探勘之後,我發現了很多引用,但沒有權威的說法是ASP.NET 管道事件之間
ExecutionContext沒有流動(除非它這樣做?)。兩者AsyncLocal和邏輯呼叫上下文都基於ExecutionContext.
最接近權威答案的是David Fowl在 GitHub 上的評論。
如果這些事件不同步執行,則這些事件不會在 ASP.NET 管道事件之間
ExecutionContext*流動。*因此,不要使用AsyncLocal或邏輯CallContext來持久化狀態;使用HttpContext.Items.更新:.NET 4.7.1 添加了一個新的回調方法,
HttpApplication.OnExecuteRequestStep根據文件,該方法“為 ASP.NET 管道提供了可擴展性,使開發人員可以輕鬆地在環境上下文場景中實現功能並建構關心 ASP.NET 執行流程的庫(例如,跟踪、分析、診斷和事務)。 ”這正是人們為了恢復ASP.NET 管道事件之間的
AsyncLocal狀態或邏輯所需要的。CallContext