abpquartz动态作业,unitofwork属性不起作用

问题描述 投票:0回答:1

我需要从 JSON 文件读取 Quartz 作业配置并使用特定作业模板(配置触发器和 IJobDetail)生成作业实例。这是动态创建作业的代码:

public class JobRunner
{
    private readonly IConfiguration _configuration;
    private readonly ISchedulerFactory _jobSchedularFactory;
    private readonly IJobFactory _jobFactory;
    public JobRunner(IConfiguration configuration, ISchedulerFactory jobSchedularFactory, IJobFactory jobFactory)
    {
        _configuration = configuration;
        _jobSchedularFactory = jobSchedularFactory;
        _jobFactory = jobFactory;
    }


    public async Task StartAsync()
    {
        IScheduler scheduler=await _jobSchedularFactory.GetScheduler();
        scheduler.JobFactory=_jobFactory;
        await CreateJob(scheduler);
    }

    private async Task CreateJob(IScheduler scheduler)
    {
        var jobs= _configuration.GetSection("Jobs").Get<List<JobOptions>>()??new ();
        foreach (var item in jobs)
        {
            if (!item.Enabled)
            {
                continue;
            }
            
            var jobData=new JobDataMap();
            jobData.Add("LineId",item.LineId);
            jobData.Add("DataSourceName",item.DataSourceName);
            IJobDetail job=JobBuilder.Create<DemoJob>()
                .WithIdentity(item.LineId!)
                .SetJobData(jobData)
                .Build();

            ITrigger trigger=TriggerBuilder.Create()
                .WithIdentity(item.LineId)
                .WithCronSchedule(item.Corn)
                .Build();

           
            await scheduler.ScheduleJob(job,trigger);
            await scheduler.Start();
        }
    }
}

模块中的配置如下:

[DependsOn(
    typeof(AbpQuartzModule)
)]
public class BackJobWorkerModule : AbpModule
{
    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        var config= context.Services.GetConfiguration();
        context.Services.AddSingleton<IConfiguration>(config);
        context.Services.AddSingleton<ISchedulerFactory, StdSchedulerFactory>();
        context.Services.AddSingleton<IJobFactory, LineJobFactory>();
        context.Services.AddSingleton<JobRunner>();
    }


    /// <inheritdoc />
    public override async Task OnPostApplicationInitializationAsync(ApplicationInitializationContext context)
    {
        await base.OnPostApplicationInitializationAsync(context);
        var runner = context.ServiceProvider.GetRequiredService<JobRunner>();
        await runner.StartAsync();
    }
}

运行器正确使用配置文件中配置的作业JSON信息来生成作业实例,并实现了自定义的JobFactory。作业模板代码是从容器中提取的。一切运行顺利,但是当尝试使用EF Core访问数据库时,出现了无法访问已处置的DbContext的错误。使用UnitOfWorkAttribute没有任何效果;仅手动使用 UnitOfWorkManager.Begin 才能正常工作。还有其他方法可以解决这个问题吗?

我搜索了相关文档和论坛,但没有找到好的解决方案。

entity-framework-core abp quartz
1个回答
0
投票

使其成为

virtual
方法:

[UnitOfWork]
public virtual async Task Execute(IJobExecutionContext context)
{
    // ...
}

来自 https://docs.abp.io/en/abp/8.1/Unit-Of-Work

  • 如果您不是通过接口注入服务(如
    IMyService
    ),那么服务的方法必须是
    virtual
    (否则,动态代理/拦截系统无法工作)。
© www.soinside.com 2019 - 2024. All rights reserved.