2009-10-13 73 views
12

所以我想知道asp.net是如何確定一個靜態屬性的,當(據我所知)asp.net是多線程的。HttpContext.Current如何在多線程環境中工作?

  • 一種理論認爲,ASP.NET傢伙爲每個請求維護一個不同的appdomain ......但這似乎不可行。
  • 另一種理論認爲.Current方法查看當前的Thread,然後使用它在一些散列表(或其他靜態存儲機制)中查找http上下文。

無論哪種方式,它似乎非常有用的技術。我想利用它,但絕對不希望被調試共享狀態的錯誤: -/

回答

8

Marc說的是最容易發生的事情,但ASP.NET實際上比ThreadStatic所做的更復雜一些,因爲單個請求實際上可以被多個線程處理..我相信會發生什麼ASP.NET是執行線程顯式地被告知切換上下文,當然宿主環境正在調度線程並且它具有哪個httpcontext需要執行的上下文,所以它找到一個線程,告訴線程應該運行哪個上下文。然後在途中發送它。

所以這個解決方案並不是那麼令人難過,因爲threadstatic更簡單,可能適合95%的時間。

15

這是不每個請求一個AppDomain。如果你想使用線程特定的狀態,請嘗試:

[ThreadStatic] 
private static int foo; 
public static int Foo {get {return foo;} set {foo = value;}} 

每個線程現在都有自己的Foo值(或者說:「富」)。

這是而不是可以輕鬆使用 - 它確實有成本,但它是一種基於每個線程共享狀態的有效方法。我曾經使用過一次,也許是兩次 - 而且我寫了很多C#。不要過度使用它...

尤其注意初始化的問題(即忘記這樣做),並記住收拾好自己等,併成爲非常小心,如果你使用任何異步代碼,因爲任何回調/工人/等將有不同的狀態。

+0

真棒,感謝這...靜態實例得到清理一旦線程死亡? – 2009-10-13 15:45:56

+3

需要注意的是,ThreadStatic在高負載情況下不可靠。 ASP.NET在線程間切換請求上下文並遷移HttpContext。任何[ThreadStatic]都會在舊線程中留下,這是一個新的請求。 – 2009-10-13 15:48:20

+0

有趣的問題......尤其是如果它是一個可能被重用的池線程; -p我的建議:如果你正在做這種類型的事情,請手動清理。 – 2009-10-13 15:48:42