拙网论坛

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 251|回复: 0

C#单个程序集代码热更新

[复制链接]

949

主题

1001

帖子

3736

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3736
发表于 2019-1-28 13:53:33 | 显示全部楼层 |阅读模式
有的时候我们想更新我们正在执行中的代码,而不想软件重启。

  微软提供的标准方法是通过应用程序域来实现代码热更新,意思就是说,把自己想要进行热更新的代码放到另外一个应用程序域中,在检测到代码需要变更的时候,卸载掉那个程序域然后重新加载来实现代码热更新。按照微软的说法,一个应用程序域是无法实现代码热更新的。

  但是,一下方法确实是可以在单个应用程序域中实现代码热更新的,本人尝试过,在公司的上班中,软件的频繁重启让人很烦,又不能在另外一个程序域中执行,所以尝试了一下办法,在一个应用程序域中改变代码是可行的。

  方法如下:假设程序集A中有类a,程序集B中有类b,b要去调用a的方法,这个情况下可以对a的部分代码(仅对方法和属性有效)进行热更新。第一步是针对类a 进行代码重写,生成一个假的A.dll,但是具有和包含真A中类,字段,属性,和方法签名,把真A的Dll放到另外一个文件夹。当B去调用A中方法的时候,假的A会通过字节数组的形式将真A保存在自己的一个Assembly(最好放在一个其他类的静态变量中,我是那么做的)变量中,并且检测真A的文件改动,当真A发生变化的时候对Assembly变量通过字节数组的形式重新赋值。这个样子就可以就可以实现部分代码热更新。

  假A对真A代码的重写原则:假a类中至少要有三个变量,一个object变量,用来存对真a对象的引用。一个Type变量,用来存储真a的类型信息,还有真A的Assembly变量。假a在初始化的时候,要初始化刚才的那三个变量,对假a方法的调用通过反射转换为对真a对象(object变量,用来存对真a对象的引用)的调用。并且把真a方法的返回结果返回回去在真A变化之后,假A重新加载真A,这个时间点之后,在被创建的假a执行的代码已经是代码变化之后真A的代码,就可以实现代码特更新。

  把真A代码重构并且生成编译出假A是一个很费劲容易出错的过程,如下是我生成假A的代码逻辑,应该是存在某些问题的(嘿嘿,主要是说明方法)
---------------------
作者:逍遥游Free
来源:CSDN
原文:https://blog.csdn.net/qq_22553301/article/details/79183793
版权声明:本文为博主原创文章,转载请附上博文链接!



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|抱朴守拙BBS

GMT+8, 2025-5-26 01:04 , Processed in 0.191492 second(s), 18 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表