2017-02-19 1 views
1

WPF 기반 응용 프로그램과 Autofac을 사용하여 Entityframework의 DbContext 종속성을 해결하고 있습니다. 아래 코드를 사용하여 데이터 모듈을 등록했습니다.WPF 응용 프로그램의 Autofac 다중 스레딩 문제

인해 저장소에 동시 통화로, 일반 시나리오에서 사용하는 동안 그러나 TPL을 사용하는 동안이 잘 작동
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(); 
    } 
} 

, 그것은한다는 오류를 생성합니다 "가 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.). 

업데이트 :

이 내가 얻을하는 데 사용되는 간단한 비동기 방식입니다 데이터 :

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가 정의됩니다. 그렇다면이 모든 호출에 대해 다른 범위를 어떻게 얻을 수 있습니까?

+0

왜 당신이 스레드 당 인스턴스가해야합니까? – MaKCbIMKo

+0

@MaKCbIMKo 실제로 테이블이 잠겨서 같은 SQL 테이블에 액세스하는 스레드가 여러 개 있습니다. "ExecuteReader에 열려 있고 사용 가능한 연결이 필요합니다. 연결의 현재 상태가 열려 있습니다."라는 예외가 있습니다. –

+0

이것은 정확히 'InstancePerLifetimeScope'의 의미입니다. 일생 범위 내에서 논리적 인 작업 단위를 랩하고 해당 범위에서 해결합니다. 이것은 모든 작업 단위가 자신의'DataContext'를 가지게하고, 이것은 쓰레드 나 연산에서 인스턴스를 공유하는 것을 방지합니다. – Steven

답변

0

지금까지 보았 듯이 _collectionService 인스턴스를 다른 이벤트 처리기에서 Constructor Injection으로 삽입하여 공유합니다.

아마 더 나은 여기 Method Injection 사용하는, 그래서 당신이 필요로하는 당신은 방법 전에 해결, 호출 당 인스턴스를 얻을 수 있습니다 :

builder.Register(c => 
{ 
    var result = new MyObjectType(); 
    var dep = c.Resolve<TheDependency>(); 
    result.SetTheDependency(dep); 
    return result; 
});