如何在不重新启动应用程序的情况下动态加载C#应用程序的一部分
本文关键字:应用程序 动态 加载 一部分 情况下 重新启动 | 更新日期: 2023-09-27 17:58:00
我的C#应用程序server.exe
对我的业务运营至关重要,理想情况下需要全天候无中断运行。代码坚如磐石,但有一件事我无法控制,那就是第三方生成的入站数据源质量很差。我偶尔会收到包含异常的数据馈送,在这种情况下我必须:
- 更新
server.exe
内的馈送处理代码以适应异常 - 重新编译
- 使用新代码重新启动
server.exe
,并允许处理语法有缺陷的提要
整个过程通常不到几分钟,但server.exe
的重新启动会导致某些非关键状态信息的重置,更糟的是,会导致依赖server.exe.
的外部过程中断
我的目标:将提要处理代码隔离到一个单独的DLL中,该DLL的内容可以在不重新启动server.exe
的情况下更新我该怎么做?
请允许我解释一下我在写这个论坛帖子之前做了什么:
馈送处理器接口已移动到一个名为common.dll
的新程序集。界面看起来像这样:
public interface IFeedProcessor{
bool ProcessFeed(String filePath); //returns false on failure, true on success
}
Server.exe
现在引用common.dll
。
饲料处理器本身已被转移到一个名为feedProcessors.dll
的新组件中。实现看起来像这样:
internal class FeedProcessor1:IFeedProcessor{
public FeedProcessor1(){}
bool ProcessFeed(String filePath){/*implementation*/return true;}
}
internal class FeedProcessor2:IFeedProcessor{
public FeedProcessor2(){}
public bool ProcessFeed(String filePath){/*implementation*/return true;}
}
[... and so on...]
feedProcessors.dll
还包含一个名为FeedProcessorUtils
的类,用于根据一些配置输入创建特定的提要处理器。它看起来像这样:
public class FeedProcessorUtils{
public static void CreateFeedProcessor(int feedType /*and other configuration params*/){
switch(feedType){
case 1:return new FeedProcessor1();
case 2:return new FeedProcessor2();
default: throw new ApplicationException("Unhandled feedType: "+feedType);
}
}
}
一切都和以前一样,但它当然不能解决我的动态加载问题;如果我用新代码更新了feedProcessors.dll
并将其复制到生产服务器,我将无法执行此操作,因为该文件正在使用中。这并不奇怪。那么解决方案是什么呢?
理想情况下,我希望能够将更新的feedProcessors.dll
复制到生产服务器,而不会出现文件使用错误,也不会重新启动server.exe
。然后,下次server.exe
调用FeedProcessorUtils.CreateFeedProcessor()时,它将从我的修订的DLL执行,而不是从旧的DLL执行。
我从哪里开始?
您希望为动态加载的DLL使用卷影复制程序集http://msdn.microsoft.com/en-us/library/ms404279(v=vs.110).aspx
听起来像是使用MEF的经典场所:http://msdn.microsoft.com/en-us/library/dd460648(v=vs.110).aspx
我建议你调查一下,并在进行过程中提出问题。
除了卷影复制选项外,您还应该创建一个AppDomain并在更改dll时进行检查,以重新启动域并重新加载dll,您可以使用FileSystemWatcher进行检查。
注意不要在AppDomains之间直接引用您的类,否则您的旧程序集将永远不会被卸载。