0

我正在尝试在 ASP.NET Core 5 Web 应用程序中使用 Hangfire。我正在使用依赖注入将各种依赖项传递给每分钟运行一次的 hangfire 任务。不幸的是,当我尝试使用实体框架核心执行查询时,我收到以下错误消息:

System.ObjectDisposedException: '无法访问已释放的上下文实例。此错误的一个常见原因是释放从依赖注入中解析的上下文实例,然后尝试在应用程序的其他地方使用相同的上下文实例。如果您在上下文实例上调用“Dispose”或将其包装在 using 语句中,则可能会发生这种情况。如果你使用依赖注入,你应该让依赖注入容器负责处理上下文实例。对象名称:“AppDbContext”。

这是我想用 Hangfire 每分钟运行的任务:

public class ReportContentGenerator : IReportContentGenerator
{
    private readonly ILogger<ImageCopier> _logger;
    private readonly CosmosDbService _cosmosDbService;
    private readonly IBlobStorageService _blobStorageService;
    private readonly AppDbContext _dbContext;

    public ReportContentGenerator(ILogger<ImageCopier> logger, IBlobStorageService blobStorageService, CosmosDbService cosmosDbService, AppDbContext appDbContext)
    {
        _logger = logger;
        _blobStorageService = blobStorageService;
        _cosmosDbService = cosmosDbService;
        _dbContext = appDbContext;
        Console.WriteLine("Image copier instantiated...");
    }

    public async void TransposeImageAnalysisIntoReportContent()
    {
        // Query CosmosDB for all orders that have not yet had their images copyed from the staging storage into the processing storage. 
        var orders = await _cosmosDbService.GetItemsAsync("SELECT * FROM c WHERE c['status']['value'] = 'Processing' OR c['status']['value'] = 'Draft' ");

        var filaments = await  _dbContext.Filaments.ToListAsync();
        var recommendationsContent = await _dbContext.ReportContents
                                                .ToListAsync();
                                                
                                                
        // Ommitted for brevity
        
    }
}

这是我的配置服务...

// Add Hangfire services.
services.AddHangfire(configuration => configuration
    .SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
    .UseSimpleAssemblyNameTypeSerializer()
    .UseRecommendedSerializerSettings()
    .UseSqlServerStorage(Configuration.GetConnectionString("DefaultConnection"), new SqlServerStorageOptions
    {
        CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
        SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
        QueuePollInterval = TimeSpan.Zero,
        UseRecommendedIsolationLevel = true,
        DisableGlobalLocks = true
    }));
services.AddHangfireServer();

services.AddMicrosoftIdentityWebAppAuthentication(Configuration, "AzureAd");
services.AddAuthentication()
   .AddJwtBearer("ApiAuth", options =>
   {
       options.Audience = Configuration["AzureAdApi:ResourceId"];
       options.Authority = $"{Configuration["AzureAdApi:Instance"]}{Configuration["AzureAdApi:TenantId"]}";
   });

services.AddSingleton(InitializeCosmosClientInstanceAsync(Configuration.GetSection("CosmosDb")).GetAwaiter().GetResult());
services.Configure<BlobStorageOptions>(Configuration.GetSection("BlobStorageOptions"));
services.AddSingleton<IBlobStorageService, BlobStorageService>();
services.AddSingleton<IImageCopier, ImageCopier>();
services.AddScoped<IReportContentGenerator, ReportContentGenerator>();

这是我在 Startup Configure 中实例化 Hangfire 任务的地方:

 public void Configure(IApplicationBuilder app, IBackgroundJobClient backgroundJobs, IWebHostEnvironment env)
 {
     //Ommitted for brevity...
     RecurringJob.AddOrUpdate<IImageCopier>(x => x.CopyImages(), Cron.Minutely);
     RecurringJob.AddOrUpdate<IReportContentGenerator>(x => x.TransposeImageAnalysisIntoReportContent(), Cron.Minutely);
      //Ommitted for brevity...
  }
4

2 回答 2

0

你必须为hangfire配置数据库连接

.NET Core 的 Hangfire 配置

于 2021-04-01T16:13:36.740 回答
0

对于遇到此问题的其他人,解决方法是将我的任务中的 void 返回类型替换为 Task 返回类型:

public async Task TransposeImageAnalysisIntoReportContent() {
     ...
}
于 2021-04-01T18:08:00.163 回答