【发布时间】:2019-03-04 05:51:35
【问题描述】:
我将ThreadPool 与通用存储库一起使用,但出现此错误;
'无法访问已处置的对象。此错误的一个常见原因是释放从依赖注入中解析的上下文,然后尝试在应用程序的其他地方使用相同的上下文实例。如果您在上下文上调用 Dispose() 或将上下文包装在 using 语句中,则可能会发生这种情况。如果你使用依赖注入,你应该让依赖注入容器负责处理上下文实例。'
private readonly AuthorizedServiceService _authorizedServiceService;
private readonly CustomerService _customerService;
public IConfigurationRoot Configuration { get; }
public UpdateService(AuthorizedServiceService authorizedServiceService, CustomerService customerService)
{
_authorizedServiceService = authorizedServiceService;
_customerService = customerService;
}
public void UpdateAllRecords()
{
_authorizedServiceService.GetByActive().ToList().ForEach(UpdateAuthorizedServiceRecords);
}
void UpdateAuthorizedServiceRecords(AuthorizedService authorizedService)
{
//UpdateStart(authorizedService);
var mywatch = new Stopwatch();
mywatch.Start();
ThreadPool.QueueUserWorkItem(new WaitCallback(state => { UpdateStart(authorizedService); }));
mywatch.Stop();
mywatch.Reset();
}
public void UpdateStart(AuthorizedService authorizedService)
{
UpdateCustomers(authorizedService);
ThreadPool.QueueUserWorkItem(new WaitCallback(state => { UpdateCustomers(authorizedService); }));
}
internal void UpdateCustomers(AuthorizedService authorizedService)
{
try
{
if (authorizedService.CustomerUpdateLocked)
return;
var carDatabaseClient = new DataCarDatabaseClient();
var result = carDatabaseClient.GetCustomers(authorizedService, authorizedService.LastCustomerUpdate);
var dataRows = Convert<Customer>(result).Select(s=>
{
s.Id = authorizedService.Code + "-" + s.DcId;
s.AuthorizedService = authorizedService;
return s;
}).ToList();
_customerService.SaveOrUpdate(dataRows.OrderBy(p=>p.Id).FirstOrDefault(),p=> p.Id != null);
}
catch (Exception e)
{
// ignored
}
}
通用存储库方法;
public void AddOrUpdate(T entity, Expression<Func<T, bool>> predicate)
{
var exists = predicate != null ? Context.Set<T>().Any(predicate) : Context.Set<T>().Any();
if (!exists)
Context.Set<T>().Add(entity);
else
Context.Set<T>().Update(entity);
Context.SaveChanges();
}
【问题讨论】:
-
每个线程/请求/任务应该有不同的上下文。确保您已在 Startup.cs (AddScoped) 中对其进行了配置,并确保如果您手动创建线程或任务,则您在上下文中
CreateScope。 -
这是我目前创建上下文的方式; services.AddDbContextPool
(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); -
使用
ThreadPool.QueueUserWorkItem时需要新建一个作用域。请参阅此答案以获取示例:stackoverflow.com/questions/47975348/… -
正如尼尔所说,当 ThredPool 启动时,
_logger对象已经被释放,因此您需要将_logger对象传递给该UpdateStart方法。 -
我在没有记录器的情况下更新了我的方法,但仍然出现错误
标签: c# asp.net-core model-view-controller threadpool