昨晚检查代码时我发现了这段代码。值得注意的是,state
通过执行泛型回调操作的 lambda 捕获。
public static void Post<TState>(TState state, Action<TState> callback){
if(SynchronizationContext.Current is SynchronizationContext currentContext)
// Use capture-semantics for state
currentContext.Post(_ => callback(state), null);
else{
callback(state);
}
}
Post
然而,本机支持直通state
,所以上面也可以这样重写......
public static void Post<TState>(TState state, Action<TState> callback){
if(SynchronizationContext.Current is SynchronizationContext currentContext)
// Use pass-thru state, not 'capture'
currentContext.Post(passedBackState => callback((TState)passedBackState), state);
else{
callback(state);
}
}
我的问题很简单......在这个特定的用例中,回调被定义在与需要传递给它的状态相同的范围内,是否有任何技术的使用捕获语义(第一个)相对于传递(第二个)有什么好处和/或缺点?就我个人而言,我喜欢第一个,因为只有一个变量,但我问的是技术的差异(如果有的话),因为两者似乎都有效。
闭包在堆上分配一个需要垃圾收集的新对象。通过状态参数传递数据不会分配(除非数据是需要装箱的值类型)。
这些分配可能会增加频繁使用的方法或长期存在的进程(例如 Web 应用程序),从而导致垃圾处理和延迟的 CPU 周期浪费。积极删除此类分配是 .NET Core 比 .NET Old 快得多的原因之一。
Roslyn 分析仪如Roslyn 堆分配分析器 https://github.com/microsoft/RoslynClrHeapAllocationAnalyzer突出显示此类隐式分配,例如对值类型进行装箱、闭包、使用params
数组等
Update
Rider's 动态程序分析 https://www.jetbrains.com/help/rider/Fixing_Issues_Found_by_DPA.html还强调了由于关闭、装箱、枚举器等造成的分配。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)