文章插图
| 总结/Edison Zhou
最近在分析现在团队的项目代码(基于.NET Framework 4.5),经常发现一个CallContext的调用,记得多年前的时候用到了它,但是印象已经不深刻了,于是现在来复习一下 。
1 CallContext是个啥?
如果说,一个对象保证全局唯一,大家肯定会想到一个经典的设计模式:单例模式 。但是,如果要使用的对象必须是线程内唯一的呢?
在.NET Framework中,Microsoft给我们设计了一个CallContext类 。
命名空间:System.Runtime.Remoting.Messaging类型完全限定名称:System.Runtime.Remoting.Messaging.CallContextCallContext类似于方法调用的线程本地存储区的专用集合对象,并提供对每个逻辑执行线程都唯一的数据槽 。数据槽不在其他逻辑线程上的调用上下文之间共享 。当 CallContext 沿执行代码路径往返传播并且由该路径中的各个对象检查时,可将对象添加到其中 。
简而言之,CallContext提供线程(多线程/单线程)代码执行路径中数据传递的能力 。
描述
线程安全
SetData
存储给定的对象并将其与指定名称关联 。
否
GetData
从System.Runtime.Remoting.Messaging.CallContext中检索具有指定名称的对象
否
LogicalSetData
将给定的对象存储在逻辑调用上下文,并将其与指定名称关联 。
是
LogicalGetData
从逻辑调用上下文中检索具有指定名称的对象 。
是
FreeNamedDataSlot
清空具有指定名称的数据槽 。
是
HostContext
获取或设置与当前线程相关联的主机上下文 。在Web环境下等于System.Web.HttpContext.Current
2 探究CallContext方法
上面介绍了CallContext提供的核心方法,下面我们就来通过实践来理解一下 。
准备工作
这里准备一个User类作为数据传递对象:
public class User{public string Id { get; set; }public string Name { get; set; }}
测试1:GetData、SetData 与 FreeNamedDataSlot测试代码很简单,就是在主线程 和 子线程之中分别传递User对象实例,看看最后的效果 。
public void TestGetSetData(){// 主线程执行Console.WriteLine($"Current ThreadId={Thread.CurrentThread.ManagedThreadId}");var user = new User(){Id = DateTime.Now.ToString(),Name = "Edison"};CallContext.SetData("key", user);var value1 = CallContext.GetData("key");Console.WriteLine(user == value1);// 异步线程执行Task.Run(() =>{Console.WriteLine($"Current ThreadId={Thread.CurrentThread.ManagedThreadId}");var value2 = CallContext.GetData("key");Console.WriteLine(value2 == null ?"NULL" : (value2 == value1).ToString());});// 主线程执行Console.WriteLine($"Current ThreadId={Thread.CurrentThread.ManagedThreadId}");value1 = CallContext.GetData("key");Console.WriteLine(value1 == user);// 清理数据槽CallContext.FreeNamedDataSlot("key");var value3 = CallContext.GetData("key");Console.WriteLine(value3 == null ?"NULL" : (value3 == value1).ToString());}
上面示例代码的运行结果如下图所示:文章插图
根据上图所示的结果,基本可以得出以下两个结论:
1、GetData、SetData方法只能用于单线程环境,如果发生了线程切换,存储的数据也会随之丢失 。
2、GetData 和 SetData 可以用于同一线程中的不同地方,传递数据 。
可以知道,要在多线程环境下使用,我们需要用到另外两个方法:LogicalSetData 与 LogicalGetData 。
测试2:LogicalGetData、LogicalSetData 与 FreeNamedDataSlot
以上关于本文的内容,仅作参考!温馨提示:如遇健康、疾病相关的问题,请您及时就医或请专业人士给予相关指导!
「四川龙网」www.sichuanlong.com小编还为您精选了以下内容,希望对您有所帮助:- windows系统怎样切换到苹果系统
- 多线程上下文切换 多线程下的调用上下文 : CallContext
- 同城跑腿用啥软件 同城配送跑腿软件好急怎么切换城市?
- 苹果双系统如何切换-小白系统教程
- 苹果windows双系统切换教程
- 苹果双系统切换按哪个按键
- 双系统怎么切换的步骤教程
- 电脑不断黑屏和桌面切换 win10返回桌面模式
- 有氧无氧循环切换减肥 全方位快速减肥
- 电脑键盘基础知识 电脑键盘功能基础知识打字切换