«Невозможно получить доступ к удаленному объекту. Распространенной причиной этой ошибки является удаление контекста, который был разрешен путем внедрения зависимости

2

Я использую 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();
}
  • 0
    У каждого потока / запроса / задачи должен быть свой контекст. Убедитесь, что он настроен таким образом в Startup.cs (AddScoped <>), и убедитесь, что, если вы вручную создаете поток или задачу, вы CreateScope в контексте.
  • 0
    вот как я создаю свой контекст в настоящее время; services.AddDbContextPool <ApplicationContext> (options => options.UseSqlServer (Configuration.GetConnectionString ("DefaultConnection")));
Показать ещё 3 комментария
Теги:
model-view-controller
asp.net-core
threadpool
generic-repository

1 ответ

1
Лучший ответ

Это происходит из-за того, что все зависимости в основном проходе расположены, когда его выполнение заканчивается, и вы пытаетесь получить к ним доступ в другом потоке. Чтобы справиться с этой ситуацией, вам нужно создать область в фоновом потоке и разрешить 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); }));
    }
 }

Ещё вопросы

Сообщество Overcoder
Наверх
Меню