首页 > 其他分享 >ABP中使用HangFire和 Magicodes.IE(文件导出)中遇到的生命周期失效的解决

ABP中使用HangFire和 Magicodes.IE(文件导出)中遇到的生命周期失效的解决

时间:2024-06-13 22:11:05浏览次数:9  
标签:Autofac 作用域 导出 HangFire LifetimeScope ABP list Magicodes var

实现功能:

1,通过Magicodes.IE(不错的文件导入及导出组件,使用近5年了),导出10W+的数据;

2,前端VUE调用导出大数据接口,报Http499超时,考虑后端用HangFire后台作业来执行具体任务,执行完成,把执行的结果返回给前端;

实现动态导出功能的服务代码如下:

 public class OutputService : ITransientDependency
 {
     private readonly IUnitOfWorkManager _unitOfWorkManager;
     private readonly IBlobContainer<BlobCommonFileContainer> _fileContainer;
     public OutputService(
         IUnitOfWorkManager unitOfWorkManager,
         IBlobContainer<BlobCommonFileContainer> fileContainer)
     {
         _fileContainer = fileContainer;
         _unitOfWorkManager = unitOfWorkManager;
     }

     public async Task Export<T>(Guid Id, string fileName, List<T> list) where T : class, new()
     {
         using (var uow = _unitOfWorkManager.Begin(requiresNew: true, isTransactional: true))
         {
             IExporter _exporter = new ExcelExporter();//导出Excel
             var result = await _exporter.ExportAsByteArray<T>(list);
             result.ShouldNotBeNull();
             await _fileContainer.SaveAsync(fileName, result).ConfigureAwait(false);
             await uow.CompleteAsync();
         }
     }
 }

调用方式一:

 此处的坑:

1,异常吞没:如果 SaveAsync 方法内部有异常处理(例如 try-catch 块),并且异常被吞没(没有被记录或重新抛出),这可能导致方法在没有明显错误的情况下失败

2,后显示加上try-catch 块,报出了异常:

System.ObjectDisposedException
  HResult=0x80131622
  Message=Instances cannot be resolved and nested lifetimes cannot be created from this LifetimeScope as it (or one of its parent scopes) has already been disposed.
  Source=Autofac
  StackTrace:
   在 Autofac.Core.Lifetime.LifetimeScope.ThrowDisposedException() 在 Autofac.Core.Lifetime\LifetimeScope.cs 中: 第 314 行
   在 Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(ResolveRequest request) 在 Autofac.Core.Lifetime\LifetimeScope.cs 中: 第 177 行
   在 Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable`1 parameters, Object& instance) 在 Autofac\ResolutionExtensions.cs 中: 第 414 行
   在 Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable`1 parameters) 在 Autofac\ResolutionExtensions.cs 中: 第 306 行
   在 Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
   在 Volo.Abp.BlobStoring.BlobNormalizeNamingService.NormalizeNaming(BlobContainerConfiguration configuration, String containerName, String blobName)
   在 Volo.Abp.BlobStoring.BlobContainer.<SaveAsync>d__22.MoveNext()
   在 Volo.Abp.BlobStoring.BlobContainerExtensions.<SaveAsync>d__0.MoveNext()

大体意思:

System.ObjectDisposedException 错误表明尝试从已经被释放(disposed)的 LifetimeScope 解析服务时出现了问题。在这种情况下,错误消息指出 Autofac 容器的一个作用域(或其父作用域)已经被释放,因此无法从中解析服务或创建嵌套的作用域。

以下是可能导致此异常的原因和解决方法:

  1. 作用域释放:

    • 确保你没有在完成请求处理之前释放了 Autofac 的作用域。在 ASP.NET Core 中,作用域通常与 HTTP 请求生命周期相关联。
  2. 依赖项注入问题:

    • 如果在 BlobContainer 或相关服务中使用了依赖注入,确保这些服务在作用域释放之前被正确解析。
  3. 异步方法和作用域:

    • 如果 SaveAsync 或其他异步方法在作用域被释放后仍在执行,它们可能会尝试解析服务,从而导致此异常。
  4. 使用 IAsyncLifetime 或 IDisposable

    • 如果你的服务实现了 IAsyncLifetime 接口,确保在 DisposeAsync 方法中正确处理了作用域。如果实现了 IDisposable,确保在对象被释放前正确处理资源。
  5. 检查 BlobNormalizeNamingService 和 BlobContainer

    • 检查 BlobNormalizeNamingService.NormalizeNaming 和 BlobContainer.SaveAsync 方法的实现,确保它们不会在作用域释放后执行。

解决问题,重新加上生命周期作用域,代码如下:

 public async Task<string> ExportFile(Guid id, List<string> exportName, List<CustomCondition> p_list)
 {
     id = Guid.NewGuid();
     using (var scope = _serviceProvider.CreateScope())
     {
         var service = scope.ServiceProvider.GetRequiredService<OutputService>();
         var _first = exportName.FirstOrDefault();
         string sql = "SELECT id,ParentItemCode,ParentItemDesc,ChildItemCode,ChildItemDesc,Qty,ChildItemUom FROM [dbo].[hx_bom]";
         var _list = await _dbDapperContext.QueryAsync<BomExportDto>(sql, null, databaseType: DatabaseType.Secondary);
         try
         {
             // 使用 service 执行工作
             await service.Export<BomExportDto>(id, _first, _list.ToList()).ConfigureAwait(false);
         }
         catch (Exception ex)
         {
             Console.WriteLine(ex.Message.ToString());
         }
         return id.ToString();
     }
 }

测试:

执行hangfire任务

 

 成功通过后台作业生成文件‘

 

标签:Autofac,作用域,导出,HangFire,LifetimeScope,ABP,list,Magicodes,var
From: https://www.cnblogs.com/netcore-vue/p/18246868

相关文章

  • 新手使用ABP框架及注意事项--纯后端
    什么是ABP?1、ABP全称为ASP.NETBoilerplateProject(ASP.NET样板项目)、诞生的主要目的就是为了让.NET程序员“秒变”架构师,将.NET企业级项目的主流开发技术、最先进的架构整合起来,让.NET工程师能够更快的开发出更好的项目2、主要特性:模块化,多租户,认证授权,虚拟文件系统,主题系统,后......
  • .NET之Hangfire快速入门和使用
    原文地址:.NET之Hangfire快速入门和使用-追逐时光者-博客园(cnblogs.com)前言:定时任务调度问题,是一个老生常谈的问题。网上有许多定时任务调度的解决方案,对于我而言很早以前主要是使用Window计划和Window服务来做任务定时执行,然后就开始使用定时任务调度框架Quartz.N......
  • Master ABP Framework(熟练掌握 ABP 框架)
    前言ABP框架是一个完整的基础框架,用于通过遵循软件开发的最佳实践和惯例来创建现代Web应用程序。ABP提供了一个高级框架和生态系统,以帮助您实施“不要重复自己”(DRY)原则并专注于您的业务代码。本书由ABP框架的创建者撰写,将帮助您从头开始全面了解ABP框架和现代Web应用程序开发......
  • ABP框架中的仓储的方法
    在ABP框架中,仓储(Repository)是用于管理实体数据存储和访问的核心组件。ABP框架提供了一个通用的仓储接口IRepository,该接口定义了用于处理实体的常用方法。下面是IRepository接口中的所有方法,这些方法可以用于执行各种CRUD(创建、读取、更新、删除)操作。IRepository<T,TKey>......
  • asp.net core 中hangfire面板的配置及使用
    Hangfire项目实践分享-Ecin-博客园(cnblogs.com) 1、定义校验授权类DyDashboardAuthorizationFilter///<summary>///Hangfire仪表盘配置授权///</summary>publicclassMyDashboardAuthorizationFilter:IDashboardAuthorizationFilter......
  • ABPVNext问题集锦-SwaggerUI的配置问题,配置Schema自动展开
    一,ABP框架中,运行的SwaggerUI中,默认情况下,不管Post还是Get等请求接口的Schema默认情况是折叠的,前端接入接口时需要一个个手动点开,如果参数过多比如100个参数 要点100次,使用不是太方便,或那种又有查询、又有新增,并且json里面各种套,对象里面有数组,数组里面套数据,  这种参数就很多了......
  • ABP 框架 AutoMapper 映射实体时提示 Unmapped members were found 缺少 FullAuditedE
    在配置MapperProfile的时候, 运行提示映射出错:对于Workflow->WorkflowDto和CreateUpdateWorkflowDto->Workflow的映射,存在没有映射的属性 IsDeleted,DeleterId,DeletionTime,LastModificationTime,LastModifierId,CreationTime和CreatorId。我之前写代码都没有映射这......
  • 为什么hangfire 界面上显示的下次执行时间与配置的定时执行时间不一致
    hangfire定时任务,定位每天晚上11点55分执行;core表达式也展示是11点55执行,但下一次执行时间,展示的是每天3点执行的任务。原因:AddOrUpdate中的TimeZoneInfo(时区)参数默认是世界Utc时间,UTC时区与我们中国时区相差八个小时。需要设置TimeZoneInfo参数设置为TimeZoneInfo.Local,使......
  • ABP-VNext 用户权限管理系统实战06---实体的创建标准及迁移
    在apb-vnext的实体的创建中可以确实字段的长度、说明、对应的表、表中给字段加的索引以项目中的订单表为例,如下:[Comment("订单主表")][Table("t_voucher_order")] [Index(nameof(VoucherCode))]publicclassOrder:AuditedAggregateRoot<Guid>,ISoftDelete,IMultiTen......
  • NET6 Hangfire 可视化配置
    Nuget<PackageReferenceInclude="Hangfire"Version="1.8.5"/><PackageReferenceInclude="Hangfire.AspNetCore"Version="1.8.5"/><PackageReferenceInclude="Hangfire.Console"Version="1......