博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基础才是重中之重~ThreadStatic静态字段在每个线程里的唯一性
阅读量:6158 次
发布时间:2019-06-21

本文共 2954 字,大约阅读时间需要 9 分钟。

static修饰符我们不会陌生,它代表静态,可以修饰你的类,方法,字段和属性等等,今天主要说一个为静态字段加ThreadStatic特性会给程序代来什么样的变化。静态字段static field,我更习惯称它为“类的字段”,即它与类的具体实例无关,对于所有线程里,它的值都是一个,即它的唯一性。

如代码:

class Instance {  static DataContext context=new LinqToSql(conn); protected  static DataContext {get{return context;}} }

上面的代码中,context为静态字段,它的值在所有线程中都是一样的,换名话说,在多个用户访问一个页面里,得到它的值都是一样的。

上面代码是一个linq to sql实现DAL层时的一个基类,它向子类公开一个数据上下文,在所有用户访问里(所有线程中)其值(内存地址)都是一样的,而在LINQTOSQL架构中,这个静态数据上下文在实现开发中会出现很多问题,所以,官方不推荐使用。

但是,如果我们引入ThreadStatic之后,结果就不同了,当字段被ThreadStatic特性修饰后,它的值在每个线程中都是不同的,即每个线程对static字段都会重新分配内存空间,就当然于一次new操作,这样一来,由于static字段所产生的问题也就没有了,这种static数据上下文是可以被接受的。

internal class DbFactory    {        #region Fields        ///         /// 每个线程,一个新的DataContext实例        ///         [ThreadStatic]        static readonly DataContext current = new DataClasses1DataContext();        #endregion        #region Contructors        #endregion        #region Properties        public static DataContext Current        {            get { return current; }        }        #endregion        #region Methods        #endregion        #region Events        #endregion    }

上面代码是一个生成LINQ上下文的工厂,你可以为每个LINQTOSQL类新建个基类,用来得到这个上下文,而具体操作类再去继承这个基类,这在微软的架构中,

会很常见,如System.Web.MVC.ControllerBase,它是Controller的基类。

///     /// DataClasses1DataContext数据库基类    ///     public abstract class DbBase    {        #region Fields        #endregion        #region Contructors        #endregion        #region Properties        public DataClasses1DataContext Db = DbFactory.Current as DataClasses1DataContext;        #endregion        #region Methods        #endregion        #region Events        #endregion    }

而具体表的CURD操作,你可以单独建立类文件,来做这件事

public class WebManageUsers_Ext : WebManageUsers { }    public class UserDAL : DbBase    {        #region Fields        #endregion        #region Contructors        #endregion        #region Properties        #endregion        #region Methods        public IQueryable
GetModel() { var linq = from data1 in base.Db.WebManageUsers join data2 in new DeptDAL().GetModel() on data1.DepartmentID equals data2.DepartmentID select new WebManageUsers_Ext { RealName = data1.RealName, WebDepartments = data2, }; return linq; } #endregion #region Events #endregion }

OK,如果将上面代码输出后,它的结果是正确的

事实上,上面我使用的复杂查询,对于这种查询,如果你的数据上下文不是static类型,它会出现异常的,一般异常为”为不能处理不同数据上下文的引用”,当然,这个提示是正常的,因为如果你的上下文为实例对象,那么,对于每个类来说,它都是不同的,都会被new一次!

当出现上面问题后,我们往往解决方法是使用static类型的上下文,而static类型本身在LINQTOSQL上就是有问题的,在进行数据更新操作时,所有线程,所有操作的LINQ缓存都是一个,在submitChange时,会出现提求混乱的情况,错误是不可预知的。所以,你不得不把所有的表关系查询都写在DAL层,将每个业务的复杂查询方法都重写一次,这样才能解决“不能数据上下文”的问题,太可怕了,呵呵。

当然,你如果提前做了表关联,使用LINQ的“立即加载”也是一个不错的方式,它可以为你节省不少代码,但它产生的SQL语句,其内查询则是select *  from table的格式,即返回了很多无用的列。

综上所述:使用线程唯一的静态数据上下文才是最好的解决方案!

本文转自博客园张占岭(仓储大叔)的博客,原文链接:,如需转载请自行联系原博主。

你可能感兴趣的文章
javascript性能优化
查看>>
多路归并排序之败者树
查看>>
java连接MySql数据库
查看>>
深入python的set和dict
查看>>
Android JSON数据解析
查看>>
DEV实现日期时间效果
查看>>
java注解【转】
查看>>
centos 下安装g++
查看>>
下一步工作分配
查看>>
Response. AppendHeader使用大全及文件下载.net函数使用注意点(转载)
查看>>
jQuery最佳实践
查看>>
centos64i386下apache 403没有权限访问。
查看>>
jquery用法大全
查看>>
PC-BSD 9.2 发布,基于 FreeBSD 9.2
查看>>
css斜线
查看>>
Windows phone 8 学习笔记(3) 通信
查看>>
Revit API找到风管穿过的墙(当前文档和链接文档)
查看>>
Scroll Depth – 衡量页面滚动的 Google 分析插件
查看>>
Windows 8.1 应用再出发 - 视图状态的更新
查看>>
自己制作交叉编译工具链
查看>>