2012-01-06 2 views
1

뷰 모델 역할을하는 2 개의 NotificationObject 객체가 있습니다. 첫 번째 NotificationObject에는 특정 컨트롤의 뷰에 바인딩되는 속성이 포함되어 있고 두 번째 NotificationObject에는 Thread 개체를 사용하는 다른 스레드에서 실행되는 코드가 있습니다. 두 번째 NotificationObject의 실행 코드에서 첫 번째 NotificationObject의 속성을 변경해야합니다. 내가 그것을하려고하면 나는 "다른 스레드가 그것을 소유하고 있기 때문에 호출하는 스레드는이 객체에 접근 할 수 없다."라는 예외를 얻는다.NotificationObject 디스패처

Windows Forms 나 Classic WPF에서와 같이 일종의 디스패처를 사용하여 이러한 속성에 액세스해야한다고 생각하지만 프리즘 MVVM에서이를 수행하는 방법을 찾을 수 없습니다. 첫 번째 NotificationObject의 속성을 변경하려면 어떻게해야합니까?

답변

4

한 스레드에서 생성 된 내용을 다른 스레드에서 업데이트하려고 시도하고 WPF가이를 허용하지 않는다고 생각합니다. 객체는 생성 된 스레드에서만 수정할 수 있습니다.

일반적으로 모든 객체는 기본 UI 스레드에서 생성되고 디스패처는 이러한 객체를 업데이트하기 위해 비동기 메시지를 UI 스레드로 전달하는 데 사용됩니다. 메인 UI 스레드를 사용해야하는 객체의 속성을 업데이트하기 위해 백그라운드 스레드에서 많은 처리 작업을 수행 할 수 있습니다. 다음과 같습니다

예를 들어

, 뭔가 작동합니다 :

MyNotificationObject obj = new MyNotificationObject; 
obj.Items = MethodThatRunsOnBackgroundThread(); 

List<SomeObject> MethodThatRunsOnBackgroundThread() 
{ 
    var list = new List<SomeObject>(); 
    // Do Work 
    Return list; 
} 

동안이되지 않습니다 그것은을 업데이트 할 수있는 메시지를 전송하기 때문에 여기에

MyNotificationObject obj = new MyNotificationObject; 
MethodThatRunsOnBackgroundThread(obj); 

void MethodThatRunsOnBackgroundThread() 
{ 
    var list = new List<SomeObject>(); 
    // Do Work 

    // This won't work since obj was created on UI thread 
    obj.Items = List<SomeObject>; 
} 

가 작동 또 다른 예이다 객체를 생성 한 UI 스레드에 객체를 추가합니다.

MyNotificationObject obj = new MyNotificationObject; 
MethodThatRunsOnBackgroundThread(obj); 

void MethodThatRunsOnBackgroundThread() 
{ 
    var list = new List<SomeObject>(); 

    // Load List 

    Application.Current.Dispatcher.BeginInvoke(DispatherPriority.Background, 
     new Action(delegate { 
      obj.Items = list; 
     })); 
} 
+0

당신의 노력에 감사드립니다, 레이첼,하지만 이미이 접근법을 시도했습니다. Dispatcher.CurrentDispatcher.Invoke가 작동하지 않습니다. 나는 Bas B의 대답에 대한 논평으로 그것을 썼다. –

+1

@ Bogdan0x400 죄송합니다. 구문이 잘못되었습니다. 'Dispatcher.CurrentDispatcher'는 현재 쓰레드의 디스패처를 리턴합니다. 따라서 백그라운드 쓰레드에서 호출하면 백그라운드 쓰레드에 대한 디스패처를 반환합니다. UI 스레드에 대한 디스패처를 얻으려면 thead UI에서 호출하거나 "Application.Current.Dispatcher"와 같은 것을 사용해야합니다. 'App.Current.Dispatcher'는 WPF 프로젝트의 시작 응용 프로그램이 기본적으로'App'라고하기 때문에 일반적으로 나타나는 문법입니다. ''이 다른 것으로 불리는 경우 대신 사용해야합니다. – Rachel

0

Application.Current.Dispatcher 거의이 고맙게도 더 이상 필요하지 않습니다 .NET 4.5에서 가장 쉬운 해결책 ..

입니다.

+0

적어도 내 프로젝트에는 Application.Current.Dispatcher와 같은 것이 없습니다. Dispatcher.CurrentDispatcher.Invoke? 이미 시도했지만 동일한 오류가 발생했습니다. –

0

모델보기의 NotificationObject가 아닌보기의 UserControl 오브젝트에서 Dispatcher를 찾아야합니다. MVVM의 모델 뷰에서 뷰를 참조하는 것은 좋지 않다고 생각하지만 아직 더 나은 솔루션을 찾지 못했습니다.