Hi,
I'm implementing a background worker class to schedule some tasks automatically. I took as code example the class "SubscriptionExpirationCheckWorker" on MultiTenancy namespace.
I'm able to search for tenants
var tenantsForEventSchedule = _tenantRepository.GetAllList(tenant => tenant.IsActive);
and also to get some tenant settings.
But when I try to search for other entities, an exception is raised with message "cannot access a disposed object" relative to the db context. The system try to access the database but the connection ha been disposed before.
I've read aspnetboilerplate documentation about UnitOfWork ; therefore, I've added [UnitOfWork] attribute before DoWork method I still have the same exception.
How can I fix this ?
Here is an extract of the code :
public class EventSchedulerWorker : PeriodicBackgroundWorkerBase, ISingletonDependency
{
private const int CheckPeriodAsMilliseconds = 1 * 60 * 60 * 100; // demo 6 minutes
private readonly IRepository<Tenant> _tenantRepository;
private readonly IRepository<ContractSchedule, long> _contractScheduleRepository;
private readonly TenantManager _tenantManager;
private readonly IAppNotifier _appNotifier;
public EventSchedulerWorker(
AbpTimer timer,
IRepository<Tenant> tenantRepository,
IRepository<ContractSchedule, long> contractScheduleRepository,
TenantManager tenantManager,
IAppNotifier appNotifier)
: base(timer)
{
_tenantRepository = tenantRepository;
_contractScheduleRepository = contractScheduleRepository;
_tenantManager = tenantManager;
_appNotifier = appNotifier;
Timer.Period = CheckPeriodAsMilliseconds;
Timer.RunOnStart = true;
LocalizationSourceName = LogisavConsts.LocalizationSourceName;
}
[UnitOfWork]
protected override async void DoWork()
{
var tenantsForEventSchedule = _tenantRepository.GetAllList(tenant => tenant.IsActive);
foreach (var tenant in tenantsForEventSchedule)
{
try
{
if (await SettingManager.GetSettingValueForTenantAsync<bool>(AppSettings.TenantEvent.Scheduler_Activated, tenant.Id) == true)
{
//define period to search contracts
var today = Clock.Now.Date;
int dayCountBeforeEventCreation = await SettingManager.GetSettingValueForTenantAsync<int>(AppSettings.TenantEvent.Scheduler_DayCount_BeforeEventCreation, tenant.Id);
var startDate = today.AddDays(-dayCountBeforeEventCreation);
bool includeSuspendedContracts = await SettingManager.GetSettingValueForTenantAsync<bool>(AppSettings.TenantEvent.Scheduler_SuspendedContractIncluded, tenant.Id);
var contractsFound = _contractScheduleRepository
.GetAll()
.Include(c => c.Contract)
.Where(cs => cs.Contract.IsActive == true)
.WhereIf(!includeSuspendedContracts, cs => cs.Contract.IsSuspended == false)
.Where(cs => cs.ScheduleDate >= startDate && cs.ScheduleDate <= today)
.ToList();
>>>>>>>>>>>> EXCEPTION HERE : "cannot access a disposed object"
4 Answer(s)
-
0
You cannot modify the method signature to be async as DoWork is called synchronously.
Wrap your await method calls in AsyncHelper.RunSync(() => AsyncMethod(...)) like this:
if (AsyncHelper.RunSync(() => SettingManager.GetSettingValueForTenantAsync<bool>(...))) { // ... }
-
0
Ok, tks for your clarification @aaron
-
0
fot me the AsyncHelper.RunSync does not help
did this help you?
-
0
the following solved the problems
using (var uow = UnitOfWorkManager.Begin()) { ... uow.Complete(); }