• 在WEB程序中小心使用"ThreadStatic"


    场景

    在WEB系统开发中,我们经常面对这样的需求:如何在一个请求中共享数据或对象实例?之前我都会用HttpContext.Current.Items。然而有一天我发现了两个事实:一、每个请求都是在一个线程中执行的;二、[ThreadStatic]可以标注某个静态字段为每个线程提供独立的存储。面对这两个发现,我得出了这个结论:可以用[ThreadStatic]替换HttpContext.Current.Items。

    问题

    可以用[ThreadStatic]替换HttpContext.Current.Items吗?

    实验

    实验素材

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    
    using System.Threading;
    using System.IO;
    
    namespace WebThreadStaticStudy
    {
        public partial class Test : System.Web.UI.Page
        {
            [ThreadStatic]
            private static DateTime? Now;
            private static int _Times = 1;
    
            protected void Page_Load(object sender, EventArgs e)
            {
                if (Now == null)
                {
                    Now = DateTime.Now;
                }
    
                if (HttpContext.Current.Items["Now"] == null)
                {
                    HttpContext.Current.Items["Now"] = DateTime.Now;
                }
    
                string content=string.Format("第{0}次,线程:{1},ThreadStatic时间:{2},HttpContext.Current.Items时间:{3}。
    "
                    , _Times++
                    , Thread.CurrentThread.ManagedThreadId
                    , Now
                    , HttpContext.Current.Items["Now"]);
    
                this.Response.Write(content);
    
                File.AppendAllText(@"F:学习项目规律化学习WebThreadStaticStudyWebThreadStaticStudyLog.txt", content);
            }
        }
    }

    实验结果

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

    结论

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

    原因分析

    WEB服务器用线程池执行每个请求,多个不同时段执行的请求还是会共享同一个线程。

    线程池中的线程是可以被重用的,当你的请求结束后,当前线程结束,这时,其它客户端可能用你上次的线程!

  • 相关阅读:
    dom4j的安装
    OWl本体语言学习笔记
    java学习笔记之链表(约瑟夫问题)
    C#打开指定文件夹及下载文件代码示例
    如何把phpStorm打造成自己的专属IDE
    SQL和TSQL之间的区别
    整数的划分(分治递归)
    整数的划分(变形)(分治递归)
    子序列 (Data_Structure)
    找球号(Hash)
  • 原文地址:https://www.cnblogs.com/longProgrammer/p/3161897.html
Copyright © 2020-2023  润新知