CallContext类

转载weixin_30723433 最后发布于2019-07-20 10:42:24 阅读数 133  收藏

System.Runtime.Remoting.Messaging.CallContext类

MSDN:

CallContext is a specialized collection object similar to a Thread Local Storage for method calls and provides data slots that are unique to each logical thread of execution. The slots are not shared across call contexts on other logical threads. Objects can be added to the CallContext as it travels down and back up the execution code path, and examined by various objects along the path.

本来是很清楚的一个说明。不知道从什么地方看到,从当前线程启动的新线程或异步线程会复制当前线程的CallContext Data。Damn! Is it so?

Code
    class Program
    {
        static void Main(string[] args)
        {
            C1<int, string> x = new C1<int, string>();
            x.Prop1 = 999;
            x.Prop2 = "bbac";
            string s = x.Prop2 + x.Prop1.ToString();
            GetSetCallContextData();
        }         private static void GetSetCallContextData()
        {
            DateTime now = DateTime.Now;
            Console.WriteLine("Set outer thread time:{0}", now);
            CallContext.SetData("now", now);             Thread.Sleep(3000);             AutoResetEvent are = new AutoResetEvent(false);
            Thread t = new Thread(new ParameterizedThreadStart((x) =>
            {
                AutoResetEvent outerAre = x as AutoResetEvent;                 object outerTime = CallContext.GetData("now");
                Console.WriteLine("Get outer thread time for inner thread:{0}", outerTime);                 DateTime innerNow = DateTime.Now;
                Console.WriteLine("Set inner thread time:{0}", innerNow);
                CallContext.SetData("now", innerNow);                 outerAre.Set();
            }));
            t.Start(are);             are.WaitOne();             DateTime theTime = (DateTime)CallContext.GetData("now");
            Console.WriteLine("Get time from outer thread:{0}", theTime);             Func<bool> m = () =>
            {
                object theTime2 = CallContext.GetData("now");
                Console.WriteLine("Get time from outer thread for async thread:{0}", theTime2);
                return true;
            };             var result = m.BeginInvoke((x) => { }, 1);
            m.EndInvoke(result);             Console.Read();
        }

经过测试发现,没错,我被人忽悠了!

可以看到,子线程和异步线程都无法访问到主线程在CallContext中保存的数据。

另外一点,当使用ASP.NET的时候,虽然线城池里的线程是复用的,但是CallContext并不在一个线程的多次使用中共享。因为CallContext是针对逻辑线程的TLS,线程池中被复用的线程是操作系统中的内核对象而不是托管对象。就像数据库连接池中保存的是非托管资源而不是托管资源。因此,先后执行的两个托管线程可能在底层复用了一个物理线程(内核对象),但并不能共享同一组CallContext数据槽。就像先后new的两个SqlConnection对象可能在底层使用了同一个物理连接,但是托管对象的属性已经被重置。

与此对照的是ThreadStaticAttribute,标记上这个特性的静态字段是往物理线程的TLS中保存数据(根据MSDN的描述猜的。具体没试过),因此如果两个托管线程对象内部使用的是同一个物理线程,则这个字段会复用(在两个线程通过这一字段访问同一个数据槽)。

哎,算了。虽让哥们闲得没事干呢?把ThreadStatic的测试代码也贴出来:

Code
   class Program
    {
        [ThreadStatic]
        static int a;         static void Main(string[] args)
        {
            ThreadPool.SetMaxThreads(1, 1);             ThreadPool.QueueUserWorkItem((x) =>
            {
                a = 1997;             });             ThreadPool.QueueUserWorkItem((x) =>
            {
                Console.WriteLine("a={0}", a);             });             Thread.Sleep(2000);
            Console.WriteLine(a);             Console.Read();         }
}

可以看到我的猜测是正确的。ThreadStatic的效果是由JIT实现的。

园子里有个牛人博客的标题是First we try, then we trust.

到我这是:Fist I guess, then I wrong, then I try, then I trust.

转载于:https://www.cnblogs.com/zhy2002/archive/2008/11/18/1335821.html

CallContext类的更多相关文章

  1. CallContext和多线程

    前一段时间正好要在某个网页程序上开一个多线程调用多个组件的尝试,这些组件是有其他团队开发的(如:印度/俄罗斯),所以修改它们的代码看起来是不太现实的,但是,令人恼火的是他们的代码中大量的用到了AppC ...

  2. Entity Framework Context上下文管理(CallContext 数据槽)

    Context上下文管理 Q1:脏数据 Q2:一次逻辑操作中,会多次访问数据库,增加了数据库服务器的压力 >在一次逻辑操作中实现上下文实例唯一 方法一:单例模式:内存的爆炸式增长 在整个运行期间 ...

  3. CallContext的LogicalCallContext在多线程环境下面公用变量

    压根名听说过这个类的看这里:如何实现对上下文(Context)数据的统一管理 原来以为CallContext就可以直接在多线程环境下面共享使用的,今天突然想到:Asp.Net环境下面,设置来设置去的, ...

  4. CallContext线程数据缓存-调用上下文

    一.CallContext 概述 命名空间:System.Runtime.Remoting.Messaging CallContext 用于提供与执行代码路径一起传送的属性集,直白讲就是:提供线程(多 ...

  5. Java类的继承与多态特性-入门笔记

    相信对于继承和多态的概念性我就不在怎么解释啦!不管你是.Net还是Java面向对象编程都是比不缺少一堂课~~Net如此Java亦也有同样的思想成分包含其中. 继承,多态,封装是Java面向对象的3大特 ...

  6. MVC5 网站开发之四 业务逻辑层的架构和基本功能

    业务逻辑层在Ninesky.Core中实现,主要功能封装一些方法通过调用数据存储层,向界面层提供服务.   目录 奔跑吧,代码小哥! MVC5网站开发之一 总体概述 MVC5 网站开发之二 创建项目 ...

  7. Asp.Net在多线程环境下的状态存储问题

    在应用开发中,我们经常需要设置一些上下文(Context)信息,这些上下文信息一般基于当前的会话(Session),比如当前登录用户的个人信息:或者基于当前方法调用栈,比如在同一个调用中涉及的多个层次 ...

  8. RBAC角色权限设计思路

    1 设计思路 为了设计一套具有较强可扩展性的用户认证管理,需要建立用户.角色和权限等数据库表,并且建立之间的关系,具体实现如下. 1.1 用户 用户仅仅是纯粹的用户,用来记录用户相关信息,如用户名.密 ...

  9. ASP.NET MVC+EF框架+EasyUI实现权限管理系列(7)-DBSession的封装

    原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(7)-DBSession的封装 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇)   (1):框架搭建    ...

随机推荐

  1. P2214 [USACO14MAR]哞哞哞Mooo Moo

    链接:Miku ---------------------- 这道题还是个背包 --------------------- 首先看一下声音的组成,对于每一个农场的声音,它是由两部分组成的 :上一个农场 ...

  2. JMeter性能监控插件PerfMon Metrics Collector

    Jmeter性能监控插件由客户端插件和服务器端程序组成. 官方文档及插件下载地址https://jmeter-plugins.org/wiki/PerfMon/ 将插件 plugins-manager ...

  3. 有多少人在面试时,被Java 如何线程间通讯,问哭了?

    正常情况下,每个子线程完成各自的任务就可以结束了.不过有的时候,我们希望多个线程协同工作来完成某个任务,这时就涉及到了线程间通信了. 本文涉及到的知识点: thread.join(), object. ...

  4. EF Core For Oracle11中Find FirstOrDefault等方法执行失败

    问题描述 最近在使用ef core连接oracle的发现Find.FirstOrDefault.Skip Task分页等等方法执行失败.使用的是docker安装的oracle11,错误如下图: 解决办 ...

  5. HTML5中input新增类型+表单新增属性+其他标签属性

    @ (猴头) Input 新增属性 email  邮箱(只在手机端有效) url  网址(只在iphone手机有效) tel  手机号(只在手机端有效) number  数字(右侧有上下按钮,只能输入 ...

  6. CSP-J2019被虐记

    -------------------------------------- (我菜到连背包都不会) ------------------------------------- 回首一想,今年的pj还 ...

  7. 13 年的 Bug 调试经验总结 【转载】

    在<Learning From Your Bugs>一文中,我写了关于我是如何追踪我所遇到的一些最有趣的bug.最近,我回顾了我所有的194个条目(从13岁开始),看看有什么经验教训是我可 ...

  8. 【NLP】暑假课作业3 - 词性标注(简单词频概率统计)

    作业任务: 使用98年人民日报语料库进行词性标注训练及测试. 作业输入: 98年人民日报语料库(1998-01-105-带音.txt),用80%的数据作为训练集,20%的数据作为验证集. 运行环境: ...

  9. 使用ASP.NET Core 3.x 构建 RESTful API - 4.1 面向外部的Model

    Entity Framework Core 使用的 Entity Model 是用来表示数据库里面的记录的. 而面向外部的 model 则表示了要传输的东西.这类 model 有时候叫做 Dto,有时 ...

  10. PIE-SDK For C++栅格数据的创建

    1.功能简介 目前在地理信息领域中数据包括矢量和栅格两种数据组织形式.每一种数据有不同的数据格式,目前PIE SDK支持多种数据格式的数据创建,下面对栅格数据格式的数据创建功能进行介绍. 2.功能实现 ...