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