十字星

  • 首页
  • 技术
  • 随笔
  • 瞎折腾
  • 平面设计
  • 文集
  • 留言
  1. 首页
  2. 技术
  3. 正文

C#动态加载卸载类库

2021-03-01 436点热度 1人点赞 0条评论

项目中有OCR识别数据功能,用的OpenCV3.4的库,实际使用中发现类库有内存泄漏问题,先想的方案是加载OpenCV类库的dll使用动态加载方式定时卸载重新加载,实际测试发现无效,后来用的方案是使用exe调用OpenCV库,使用进程间通讯传值给主程序,定时重启exe程序解决的.本文主要记录动态加载/卸载类库的内容.

1.在需要调用项目中新建类库CanUnLoadClass并继承自MarshalByRefObject,在类CanUnLoadClass中使用反射机制加载被调用方

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

namespace WinFormsOCR
{
    public class CanUnLoadClass : MarshalByRefObject
    {
        Assembly assemble = null;
        IDisposable bb = null;
        public void LoadAssembly(int millSecond, int x, int y, int width, int height, IntPtr mainWindowHandle)
        {
            assemble = Assembly.LoadFile(AppDomain.CurrentDomain.BaseDirectory + "\\OCR340.dll");//被调用dll
            bb = (IDisposable)assemble.CreateInstance(
                "OCR340.HelperOcr340",//要实例化的类,完整名称[命名空间.类名]
                true,
                BindingFlags.Default,
                null,
                new object[] { millSecond, x, y, width, height, mainWindowHandle },//要实例化类的构造函数参数数组,和构造函数一一对应
                null,
                null);
        }

        public void Close()
        {
            if (bb != null) { bb.Dispose(); }
        }
    }
}

2.加载/卸载类库方法

AppDomain tmpAppDomain = null;
private void StartOCR340()
{
    StopOCR340();

    tmpAppDomain = AppDomain.CreateDomain("Ocr340Domain" + Environment.TickCount);//为应用程序域起个名字
    CanUnLoadClass obj = (CanUnLoadClass)tmpAppDomain.CreateInstanceFromAndUnwrap(@"WinFormsOCR.exe", "WinFormsOCR.CanUnLoadClass");//第一个参数是CanUnLoadClass所在程序集名称,第二个参数是CanUnLoadClass完整名称[命名空间.类名]
    obj.LoadAssembly(GlobalStatic.OCRMillSecond, 
        GlobalStatic.OCRX, GlobalStatic.OCRY, GlobalStatic.OCRWidth, GlobalStatic.OCRHeight, 
        GlobalStatic.MainWindowHandle);
    Console.WriteLine("加载应用程序域:" + tmpAppDomain.FriendlyName);
}

private void StopOCR340()
{
    try
    {
        if (tmpAppDomain != null)
        {
            string str = tmpAppDomain.FriendlyName;
            AppDomain.Unload(tmpAppDomain);
            tmpAppDomain = null;
            GC.Collect();
            Console.WriteLine("卸载应用程序域:" + str);
        }
    }
    catch { }
}

3.正常程序运行时已加载的dll是无法删除的,验证是否卸载成功,只要看dll能否删除即可

4.完整源码链接 OCR识别动态加卸载dll

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可
标签: C# WinForm
最后更新:2021-10-30

cxw

技术宅,最喜瞎折腾.

点赞
< 上一篇
下一篇 >

文章评论

取消回复

最新 热点 随机
最新 热点 随机
删除名称最后带空格的文件夹 esxi无法直通sata控制器,只能使用rdm直通硬盘 Esxi总是会话超时需要重新登录,修改配置,增加超时时间 WinAPI函数SetupDiEnumDeviceInterfaces始终返回false解决方案 删除tmp文件夹内容导致网站503 Service Unavailable解决 SQL Server 附加数据库出错,操作系统错误 5:"5(拒绝访问。)" 错误:5120
删除tmp文件夹内容导致网站503 Service Unavailable解决esxi无法直通sata控制器,只能使用rdm直通硬盘WinAPI函数SetupDiEnumDeviceInterfaces始终返回false解决方案Esxi总是会话超时需要重新登录,修改配置,增加超时时间删除名称最后带空格的文件夹
针对上一篇《单例模式基类如何初始化子类》中有关线程启动停止的优化 WordPress5.5版本如何使用自带站点地图sitemap C# String类型JSON数组转为JArray类型 SQL2008对加密的存储过程解密 eclipse导入已存在web项目编译报错 WordPress使用Kratos主题,不用插件实现存档模板
标签聚合
C# CentOS WinForm PHP Excel WordPress W10 Hyper-V Linux IT
最近评论
alex 发布于 1 年前(01月22日) 博主,请问把代码贴到博客里可以复制是怎么实现的

COPYRIGHT © 2021 十字星. ALL RIGHTS RESERVED

THEME KRATOS MADE BY VTROIS

京ICP备2020032489号-1