.NET:在WEB程序中小心使用 “ThreadStatic”


場景

在WEB系統開發中,我們經常面對這樣的需求:如何在一個請求中共享數據或對象實例?之前我都會用HttpContext.Current.Items。然而有一天我發現了兩個事實:一、每個請求都是在一個線程中執行的;二、[ThreadStatic]可以標注某個靜態字段為每個線程提供獨立的存儲。面對這兩個發現,我得出了這個結論:可以用[ThreadStatic]替換HttpContext.Current.Items。

問題

可以用[ThreadStatic]替換HttpContext.Current.Items嗎?

實驗

實驗素材

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Web;
 5 using System.Web.UI;
 6 using System.Web.UI.WebControls;
 7 
 8 using System.Threading;
 9 using System.IO;
10 
11 namespace WebThreadStaticStudy
12 {
13     public partial class Test : System.Web.UI.Page
14     {
15         [ThreadStatic]
16         private static DateTime? Now;
17         private static int _Times = 1;
18 
19         protected void Page_Load(object sender, EventArgs e)
20         {
21             if (Now == null)
22             {
23                 Now = DateTime.Now;
24             }
25 
26             if (HttpContext.Current.Items["Now"] == null)
27             {
28                 HttpContext.Current.Items["Now"] = DateTime.Now;
29             }
30 
31             string content=string.Format("第{0}次,線程:{1},ThreadStatic時間:{2},HttpContext.Current.Items時間:{3}。\r\n"
32                 , _Times++
33                 , Thread.CurrentThread.ManagedThreadId
34                 , Now
35                 , HttpContext.Current.Items["Now"]);
36 
37             this.Response.Write(content);
38 
39             File.AppendAllText(@"F:\學習項目\規律化學習\WebThreadStaticStudy\WebThreadStaticStudy\Log.txt", content);
40         }
41     }
42 }

實驗結果

 1 第1次,線程:8,ThreadStatic時間:2013/5/3 11:22:06,HttpContext.Current.Items時間:2013/5/3 11:22:06 2 第2次,線程:10,ThreadStatic時間:2013/5/3 11:22:08,HttpContext.Current.Items時間:2013/5/3 11:22:08 3 第3次,線程:8,ThreadStatic時間:2013/5/3 11:22:06,HttpContext.Current.Items時間:2013/5/3 11:22:08 4 第4次,線程:10,ThreadStatic時間:2013/5/3 11:22:08,HttpContext.Current.Items時間:2013/5/3 11:22:09 5 第5次,線程:11,ThreadStatic時間:2013/5/3 11:22:10,HttpContext.Current.Items時間:2013/5/3 11:22:10 6 第6次,線程:10,ThreadStatic時間:2013/5/3 11:22:08,HttpContext.Current.Items時間:2013/5/3 11:22:10 7 第7次,線程:8,ThreadStatic時間:2013/5/3 11:22:06,HttpContext.Current.Items時間:2013/5/3 11:22:10 8 第8次,線程:11,ThreadStatic時間:2013/5/3 11:22:10,HttpContext.Current.Items時間:2013/5/3 11:22:11 9 第9次,線程:8,ThreadStatic時間:2013/5/3 11:22:06,HttpContext.Current.Items時間:2013/5/3 11:22:1210 第10次,線程:11,ThreadStatic時間:2013/5/3 11:22:10,HttpContext.Current.Items時間:2013/5/3 11:22:12。

結論

不可以用[ThreadStatic]替換HttpContext.Current.Items。

原因分析

WEB服務器用線程池執行每個請求,多個不同時段執行的請求還是會共享同一個線程。

張占嶺 :線程池中的線程是可以被重用的,當你的請求結束后,當前線程結束,這時,其它客戶端可能用你上次的線程!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM