作者 | 马超 责编 | 张红月
出品 | CSDN博客
上次用C#写.Net代码差不多还是10多年以前 , 由于当时Java已经颇具王者风范 , .Net几乎被打得溃不成军 。 因此当时笔者对于这个.Net的项目态度比较敷衍了事 , 没有对其中一些优秀机制有很深的了解 , 在去年写《C和Java没那么香了 , 高并发时代谁能称王》时都没给.Net以一席之地 , 不过最近恰好机缘巧合 , 我又接手了一个Windows方面的项目 , 这也让我有机会重新审视一下自己关于.Net框架的相关知识 。
项目原型要实现的功能并不复杂 , 主要就是记录移动存储设备中文件拷出的记录 , 而且需要尽可能少的占用系统资源 , 而在开发过程中我无意中加了一行看似没有任何效果的代码 , 使用Invoke方法记录文件拷出情况 , 这样的操作却让程序执行效率明显会更高 , 这背后的原因特别值得总结 。
一行没用的代码却提高了效率?
由于笔者需要记录的文件拷出信息并没有回显在UI的需要 , 因此也就没考虑并发冲突的问题 , 在最初版本的实现中 , 我对于filesystemwatcher的回调事件 , 都是直接处理的 , 如下:
但是一个非常偶然的机会 , 我使用了Event/Delegate的Invoke机制 , 结果发现这样一个看似的废操作 , 却让程序的CPU占用率下降到0.2%左右
看似没用的Invoke到底有什么用
这里先给出结论 , Invoke能提升程序执行效率 , 其关键还是在于线程在多核之间切换的消耗要远远高于拆、装箱的资源消耗 , 我们知道我们程序的核心就是操作files这个共享变量 , 每次在被检测的U盘目录中如果发生文件变动 , 其回调通知函数可能都运行在不同的线程 , 如下:
文章图片
Invoke机制的背后其实就是保证所有对于files这个共享变量的操作 , 全部都是由一个线程执行完成的 。
文章图片
目前.Net的代码都开源的 , 下面我们大致讲解一下Invoke的调用过程 , 不管是BeginInvoke还是Invoke背后其实都是调用的MarshaledInvoke方法来完成的 , 如下:
特别声明:本站内容均来自网友提供或互联网,仅供参考,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
