Я работаю с приложением на основе WPF и использую Autofac для разрешения зависимости DbContext от Entityframework. Я использовал приведенный ниже код для регистрации моего модуля данных.Проблема многопоточности с Autofac в приложении WPF
public class DataModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<DataContext>()
.As<IDbContext>()
.WithParameter("nameOrConnectionString", "DefaultConnectionString")
.InstancePerLifetimeScope();
builder.RegisterGeneric(typeof(Repository<>))
.As(typeof(IRepository<>))
.InstancePerLifetimeScope();
}
}
Это прекрасно работает при использовании в обычном сценарии, но при использовании TPL, из-за одновременные вызовы в хранилище, он создает ошибку о том, что «ExecuteReader требует открытого и доступного подключения. Текущее состояние соединения с использованием открыто.»
В веб-приложении это может быть разрешено с помощью экземпляра InstancePerRequest для разрешения зависимости для каждого запроса, но в WPF мне нужно разрешить эту зависимость для запроса на поток. Есть ли выход для этого?
У меня есть обзор резюме InstancePerRequest или autofac и заявляет, что этот метод используется для веб-запроса только:
// Summary:
// Share one instance of the component within the context of a single web/HTTP/API
// request. Only available for integration that supports per-request dependencies
// (e.g., MVC, Web API, web forms, etc.).
Update:
Это простой метод асинхронной, который я использовал, чтобы получить данные:
private async void OnLoadClientDetail()
{
long clientId = SelectedClient != null ? SelectedClient.Id : 0;
var listOfCollection = await _collectionService.GetCollectedCollectionAsync(clientId);
CollectionList = new ObservableCollection<CollectedCollection>(listOfCollection);
}
Здесь OnLoadClientDetail привязан к событию изменения выбора выпадающего списка. Когда пользователь часто меняет выбор, этот метод будет вызываться несколько раз. _collectionService вводится в viewmodel и имеет значение InstancePerLifetimeScope. Итак, как я могу получить разные возможности для всех этих вызовов?
Почему вам нужно иметь экземпляр для каждого потока? – MaKCbIMKo
@MaKCbIMKo На самом деле существует несколько потоков, обращающихся к одной и той же таблице SQL, из-за которой таблица заблокирована, и я получил исключение. ExecuteReader требует открытого и доступного соединения. Текущее состояние соединения открыто. " –
Это именно то место, где предназначен «InstancePerLifetimeScope». Вы завершаете логическую единицу работы в пределах срока действия и решаете эту область. Это гарантирует, что каждая единица работы имеет свой собственный «DataContext», и это предотвращает совместное использование экземпляров по потокам или операциям. – Steven