简体   繁体   English

如何在不重新启动应用程序的情况下让我的C#应用​​程序的一部分动态加载?

[英]How can I get a portion of my C# app to load dynamically without app restart?

My C# application server.exe is critical to my business operations and ideally needs to run without interruption 24/7. 我的C#应用​​程序server.exe对我的业务运营至关重要,理想情况下,它需要24/7不间断运行。 The code is rock solid but one thing that's out of my control is the poor quality of inbound data feeds that are generated by third parties. 该代码固若金汤,但我无法控制的是第三方生成的入站数据提要的质量很差。 I'll occasionally receive data feeds that contain anomalies in which case I must: 我偶尔会收到包含异常的数据提要,在这种情况下,我必须:

  • update the feed processing code within server.exe to accommodate the anomaly 更新server.exe的提要处理代码以适应异常
  • recompile 重新编译
  • restart server.exe using the new code and allow the syntactically flawed feed to be processed 使用新代码重新启动server.exe并允许处理语法上有缺陷的提要

The whole process usually takes less than a couple of minutes but the restart of server.exe causes the reset of certain non-critical state information and worse, causes a disruption of external processes that depend upon server.exe. 整个过程通常花费不到几分钟,但是server.exe的重新启动会导致某些非关键状态信息的重置,更糟糕的是,会导致依赖server.exe.的外部进程中断server.exe.

My goal: Isolate the feed processing code into a separate DLL whose contents can be updated without restarting server.exe . 我的目标: 将提要处理代码隔离到一个单独的DLL中,无需重新启动server.exe即可更新其内容。 How do I do this? 我该怎么做呢?

Allow me to explain what I've done so far prior to writing this forum post: 在撰写此论坛帖子之前,请允许我解释我到目前为止所做的事情:

The feed processor interface has been moved to a new assembly called common.dll . 提要处理器接口已移至名为common.dll的新程序集。 The interface looks something like this: 该界面如下所示:

public interface IFeedProcessor{
    bool ProcessFeed(String filePath);  //returns false on failure, true on success
}

Server.exe now references common.dll . Server.exe现在引用common.dll

The feed processors themselves have been moved to a new assembly called feedProcessors.dll . 提要处理器本身已移至名为feedProcessors.dll的新程序feedProcessors.dll The implementations look something like this: 实现看起来像这样:

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 also contains a class named FeedProcessorUtils that's used to create a specific feed processor based on some configuration inputs. feedProcessors.dll还包含一个名为FeedProcessorUtils的类,该类用于基于一些配置输入来创建特定的提要处理器。 It looks something like this: 看起来像这样:

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);
        }
    }
}

Everything works just as before but of course it doesn't solve my dynamic loading problem; 一切都像以前一样工作,但是当然不能解决我的动态加载问题; If I updated feedProcessors.dll with new code and copy it to the production server, I'm unable to do so because the file is in use. 如果我使用新代码更新feedProcessors.dll并将其复制到生产服务器,则由于文件正在使用中,因此无法执行此操作。 No surprise there. 毫不奇怪。 So what's the solution? 那么解决方案是什么?

Ideally I want to be able to copy an updated feedProcessors.dll to the production server without a file-in-use error and without restarting server.exe . 理想情况下,我希望能够将更新的feedProcessors.dll复制到生产服务器,而不会出现使用中文件错误并且无需重新启动server.exe Then, the next time server.exe makes a call to FeedProcessorUtils.CreateFeedProcessor(), it'll be executing from my revised DLL instead of the old one. 然后,下次server.exe调用FeedProcessorUtils.CreateFeedProcessor()时,它将从我修订的 DLL(而不是旧的DLL)中执行。

Where do I start? 我从哪里开始?

您要对动态加载的DLL使用卷影复制程序集http://msdn.microsoft.com/zh-cn/library/ms404279(v=vs.110).aspx

Sounds like a classic place to use MEF: http://msdn.microsoft.com/en-us/library/dd460648(v=vs.110).aspx 听起来像是使用MEF的经典场所: http : //msdn.microsoft.com/zh-cn/library/dd460648( v= vs.110).aspx

I suggest you look into it and ask questions as you proceed. 我建议您调查一下并在继续进行时提问。

In addition to the shadow copy option, you should create an AppDomain and check when your dll is changed to restart the domain and reload the dll , you can check this with a FileSystemWatcher . 除了卷影复制选项,您还应该创建一个AppDomain并检查将dll更改为重新启动域并重新加载dll的时间 ,您可以使用FileSystemWatcher进行检查。

Take care of not directly referencing your classes between AppDomains , or your old assembly will never be unloaded. 注意不要在AppDomains之间直接引用您的类 ,否则您的旧程序集将永远不会被卸载。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在不使用C#刷新应用程序的情况下动态读取文件夹中的XML文件? - How can I dynamically read XML files in a folder without refreshing my app using C#? 如何在我的C#应用​​程序中获得与Spy ++类似的功能? - How can I get functionality similar to Spy++ in my C# app? 如何将当前应用程序域的程序集动态加载到 C# 项目? - How to load assemblies to the current app domain to the c# project dynamically? C# 如何在后台隐藏我的应用程序? - C# How can i hide my app in the background? 如何重新启动dotnetcore 2 C#控制台应用程序 - How to restart dotnetcore 2 C# Console app 如何在不触碰C#应用程序的主要代码的情况下为表单及其创建的所有子表单设置默认字体? - How can i set the default font for my form and all child forms it creates, without touching the main code of the c# app? 如何让我的 C# API 响应来自我的 React 应用程序的 POST 请求? (CORS问题) - How can I get my C# API to respond to a POST request from my React app? (CORS issue) 如何使用运行我的 Windows App Store 应用程序的 C# 获取当前目录? - How do I get the current directory using C# that my Windows App Store app is running in? 如何在不关闭 C# xamarin forms android 的应用程序的情况下关闭侧边栏? - How could I close my sidebar without closing my app in C# xamarin forms android? 如何让我的客户端 - 服务器应用程序成为多客户端服务器应用程序? C# - How can i make my client-server app a multiclient-server app? C#
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM