C# abp.io Hangfire无法访问已释放的上下文实例

C# abp.io Hangfire无法访问已释放的上下文实例,c#,asp.net-core,hangfire,abp,C#,Asp.net Core,Hangfire,Abp,我试图在应用程序启动时设置一个Hangfire重复作业,但如果我尝试在作业中使用注入式IRepository;它给了我这个错误 System.ObjectDisposedException Cannot access a disposed context instance. A common cause of this error is disposing a context instance that was resolved from dependency injection and the

我试图在应用程序启动时设置一个Hangfire重复作业,但如果我尝试在作业中使用注入式IRepository;它给了我这个错误

System.ObjectDisposedException
Cannot access a disposed context instance. A common cause of this error is disposing a context instance that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling 'Dispose' on the context instance, or wrapping it in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances. Object name: 'TMSDbContext'.

System.ObjectDisposedException: Cannot access a disposed context instance. A common cause of this error is disposing a context instance that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling 'Dispose' on the context instance, or wrapping it in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.
Object name: 'TMSDbContext'.
   at Microsoft.EntityFrameworkCore.DbContext.CheckDisposed()
   at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies()
   at Microsoft.EntityFrameworkCore.DbContext.get_Model()
   at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.get_EntityType()
   at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.CheckState()
   at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.get_EntityQueryable()
   at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.System.Linq.IQueryable.get_Provider()
   at Volo.Abp.EntityFrameworkCore.EfCoreAsyncQueryableProvider.CanExecute[T](IQueryable`1 queryable)
   at Volo.Abp.Linq.AsyncQueryableExecuter.<>c__DisplayClass4_0`1.<FindProvider>b__0(IAsyncQueryableProvider p)
   at System.Linq.Enumerable.TryGetFirst[TSource](IEnumerable`1 source, Func`2 predicate, Boolean& found)
   at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
   at Volo.Abp.Linq.AsyncQueryableExecuter.FindProvider[T](IQueryable`1 queryable)
   at Volo.Abp.Linq.AsyncQueryableExecuter.ToListAsync[T](IQueryable`1 queryable, CancellationToken cancellationToken)
   at Volo.Abp.Domain.Repositories.RepositoryAsyncExtensions.ToListAsync[T](IReadOnlyRepository`1 repository, CancellationToken cancellationToken)
   at MB.TMS.Application.BackgroundServices.Hangfire.BookingAlarmFunction() in C:\Users\ahmad\source\repos\TMS-Abp4\aspnet-core\src\MB.TMS.Application\BackgroundServices\Hangfire.cs:line 53
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
我已在ApplicationModule中将我的服务注册为作用域服务

 public override void ConfigureServices(ServiceConfigurationContext context)
        {
            Configure<AbpAutoMapperOptions>(options =>
            {
                options.AddMaps<TMSApplicationModule>();
            });


            context.Services.AddScoped<IHangfire, Hangfire>();
        }
公共覆盖无效配置服务(ServiceConfigurationContext)
{
配置(选项=>
{
options.AddMaps();
});
context.Services.addScope();
}
我的工作方法只是尝试使用注入的存储库进行查询

    public class Hangfire : IHangfire
    {
    
        private readonly IRepository<Booking, int> _bookingsRepository;
        private readonly IBookingSignalR _bookingSignalR;
        private readonly IObjectMapper _objectMapper;

        public Hangfire(
            IRepository<Booking, int> bookingsRepository,
            IBookingSignalR bookingSignalR,
            IObjectMapper objectMapper)
        {
            _bookingsRepository = bookingsRepository;
            _bookingSignalR = bookingSignalR;
            _objectMapper = objectMapper;
        }
    
        public void BookingAlarmRecurringJob()
        {
        RecurringJob.AddOrUpdate(
        () => BookingAlarmFunction(),
        Cron.Minutely());
        }

        [UnitOfWork]
        public virtual async Task BookingAlarmFunction()
        {
            

            var bookings = await _bookingsRepository
                                        .ToListAsync();

            bookings.ForEach(async booking =>
            {
                if (IsPlanningAlramActive(booking))
                {
                    booking.IsPlanningAlarmActive = true;
                    await SendSignalR(booking);

                }

                else if (IsPickupAlarmActive(booking))
                {
                    booking.IsPlanningAlarmActive = false;
                    booking.IsPickupAlarmActive = true;
                    await SendSignalR(booking);
                }
            });

        }
    }
}
public-class-Hangfire:IHangfire
{
私人只读IRepository\u bookingsRepository;
私人只读IBookingSignalR\u bookingSignalR;
私有只读IObjectMapper\u objectMapper;
公共绞刑(
IRepository Bookings存储库,
IBookingSignal预订信号机,
IObjectMapper(对象映射器)
{
_bookingsRepository=bookingsRepository;
_bookingSignalR=bookingSignalR;
_objectMapper=objectMapper;
}
公共作废预订LarmRecurringJob()
{
RecurringJob.AddOrUpdate(
()=>BookingAlarmFunction(),
Cron.Minutely());
}
[工作单元]
公共虚拟异步任务BookingAlarmFunction()
{
var bookings=等待_bookings存储库
.ToListAsync();
bookings.ForEach(异步预订=>
{
if(iPlanningalRamactive(预订))
{
booking.IsPlanningAlarmActive=true;
等待发送信号员(预订);
}
其他如果(ISPICKUPLARMACTIVE(预订))
{
booking.IsPlanningAlarmActive=false;
booking.ispickupalaractive=true;
等待发送信号员(预订);
}
});
}
}
}

手动在BookingAlarmFunction方法中创建uow实现了这一点

public class Hangfire : IHangfire
    {
        private readonly IUnitOfWorkManager _unitOfWorkManager;

        public Hangfire(
            IUnitOfWorkManager unitOfWorkManager)
        {
            _unitOfWorkManager = unitOfWorkManager;
        }

        public virtual async Task BookingAlarmFunction()
        {
            using (var uow = _unitOfWorkManager.Begin(requiresNew: true, isTransactional: true))
            {
                var bookings = await _bookingsRepository
                                       .ToListAsync();

                await uow.CompleteAsync();
            }

        }
}

这回答了你的问题吗?或者只使用常规的foreach循环而不是linq方法。您的问题是您没有等待
预订中的整个任务集合。ForEach()
我认为这不足以将
IHangfire
注册为范围服务,您需要创建范围:@franzgleichman当我尝试从数据库获取预订时,会发生异常。它够不着foreach@Artur我已经在方法级别创建了一个服务范围,但仍然给出相同的错误
IServiceScope范围=\u serviceProvider.CreateScope()
IRepository\u bookingsRepository=scope.ServiceProvider.GetRequiredService()
public class Hangfire : IHangfire
    {
        private readonly IUnitOfWorkManager _unitOfWorkManager;

        public Hangfire(
            IUnitOfWorkManager unitOfWorkManager)
        {
            _unitOfWorkManager = unitOfWorkManager;
        }

        public virtual async Task BookingAlarmFunction()
        {
            using (var uow = _unitOfWorkManager.Begin(requiresNew: true, isTransactional: true))
            {
                var bookings = await _bookingsRepository
                                       .ToListAsync();

                await uow.CompleteAsync();
            }

        }
}