• Microsoft.Extensions.DependencyInjection不同版本导致EF出现内存泄露。


    我的代码里将IServiceProvider放入ServiceLocator中遇到的问题。

    注:以下所有例子都是Console里的结论,AspNetCore里不管怎么玩都没有问题,有其他帖子测试出在Asp.net Core里也存在问题,具体他怎么一个写法导致的没细研,在目前我自己项目中用到的范围内Web环境一切OK。

    方案1:每次获取IServiceProvider 需要_services.BuildServiceProvider(); ;其中private static IServiceCollection _services; 为静态。

    public static class ServiceLocator
        {
            private static IServiceCollection _services;
    
            public static IServiceProvider Instance
            {
                get
                {
                    if (_services == null)
                        return null;
                    else
                        return _services.BuildServiceProvider();
                }
            }
    
            public static void Init(IServiceCollection services)
            {
                _services = services;
            }
        }

    方案2:每次获取IServiceProvider 直接取IServiceProvider的静态属性; 其中public static IServiceProvider ServiceProvider { get; private set; }为静态。

    public static class ServiceLocator
    {
        private static IServiceProvider _servicesProvider;
    
        public static IServiceProvider Instance
        {
            get
            {
              return _servicesProvider;
            }
        }
    
        public static void Init(IServiceCollection services)
        {
            _servicesProvider = services.BuildServiceProvider();
        }
    }         

    EF6或dapper项目中使用Microsoft.Extensions.DependencyInjection1.0 时,用方案1正确,用方案2会出现内存泄露。

    使用EF Core2.0时(强依赖于Microsoft.Extensions.DependencyInjection2.0),用方案2正确,用方案1会出现内存泄露。

    使用EF Core2.0且用方案1时,可以把官方扩展方法AddDbContext替换为以下代码避免出现内存泄露:

    var options = new DbContextOptionsBuilder<XXDbContext>().UseSqlServer("connstr").Options;
    services.AddScoped(s => new XXDbContext(options));  感谢Jeffcky提供此方法

    目前我用EF Core2.0 ,使用了方案2,感觉存个静态的IServiceProvider也更合理。

    刨根究底的事,等有空老衲深入研究下。

    另:若使用像Orleans的Actor模型这类具有高度隔离性的东东,慎用Scoped级别的DbContext,一个DbContext同时跨多个Actor导致事务失效。

  • 相关阅读:
    socket.io的抽象实现:engine.io
    Juicer javascript 模板引擎
    phonegap 开发案例
    安卓升级提示 phoneGap APK软件更新提示
    搭建Titanium开发环境
    phonegap WebApp
    vue-cli 配置vue项目环境笔记
    从一张表里面查询后十条数据的前七条
    js实现文字搬运工
    MySQL —— 数据库数据备份命令 mysqlump 的使用
  • 原文地址:https://www.cnblogs.com/wintersoft/p/9100425.html
Copyright © 2020-2023  润新知