c# - '无法访问已处置的对象。此错误的一个常见原因是处理从依赖注入(inject)中解析的上下文

标签 c# asp.net-core model-view-controller threadpool

我将 ThreadPool 与通用存储库一起使用,但出现此错误;

'Cannot access a disposed object. A common cause of this error is disposing a context 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, or wrapping the context in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.'

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();
}

最佳答案

发生这种情况是因为主线程中的所有依赖项在其执行完成时被释放,而您正试图在另一个线程中访问它们。要处理这种情况,您需要在后台线程中创建一个作用域并在那里解析 AuthorizedServiceService:

private readonly IServiceScopeFactory _scopeFactory;

public UpdateService(AuthorizedServiceService authorizedServiceService, CustomerService customerService, IServiceScopeFactory scopeFactory)
{
    _authorizedServiceService = authorizedServiceService;
    _customerService = customerService;
    _scopeFactory = scopeFactory;
}

public void UpdateStart(AuthorizedService authorizedService)
{    
    ThreadPool.QueueUserWorkItem(new WaitCallback(state => { 
    using (scope = _scopeFactory.CreateScope())
    {
        var scopedAuthorizedService = scope.ServiceProvider.GetService(typeof(AuthorizedServiceService));
        UpdateCustomers(scopedAuthorizedService); }));
    }
 }

关于c# - '无法访问已处置的对象。此错误的一个常见原因是处理从依赖注入(inject)中解析的上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52551821/

相关文章:

c# - 测试类型是否是属性?

c# - 如何将 'pass parameter' 添加到自定义 AuthorizeAttribute

asp.net-core - 无法使用 EF Core 1.1 创建迁移

c# - 如何运行代码优先迁移到多个租户(由架构分隔)

c# - 你把集合类放在哪里?

c# - 在 C# 中使用小数进行转换

c# - 将数据从 View 传递到 Controller asp.net core razor 页面

asp.net-core - 在 web.config 中未检测到 system.identityModel

ruby-on-rails - 通过父 Controller 更新嵌套资源并查看?

java - SpringMVC 中 Redirect 或 RedirectModel 问题的解决方案