2009-07-02 6 views
3

첫째, 백그라운드 스레드 이외의 스레드에서 스레드 정렬을 수정하는 데 많은 질문과 해결책이 있다는 것을 알고 있습니다. 내가 찾은 모든 질문과 해결책은 목록 또는 비즈니스 개체 자체가 Windows 양식이 구독 할 수있는 이벤트를 제기 한 다음 주 UI 스레드에 대한 업데이트를 올바르게 마샬링하는 시나리오에 중점을 둡니다.Winforms UI 스레드 백그라운드 스레드에서 업데이트되는 BusinessObject 목록 마샬링

제 경우 비즈니스 개체 목록이 별도의 레이어에있는 백그라운드 스레드에 의해 업데이트되고 있습니다. 이 목록을 주 스레드의 컨트롤에 바인딩하고 싶습니다. 업데이트가 올바르게 정렬 될 수 있도록 비즈니스 객체 목록에서 UI에 이벤트를 표시해야합니까? 비즈니스 개체 목록을 자동으로 업데이트하고 목록 업데이트 이벤트를 UI에 노출시키지 않고 이러한 업데이트를 UI에 전파 할 수 있습니까?

편집 :

내 문제는 본질적으로 이것이다 : 속성을 변경 한 후 INotifyProperty 해고되고 변경되었습니다. 이벤트를 발생시키는 thread가 UI thread가 아닌 경우,이 인터페이스를 구현하는 객체에 바인드 된 컨트롤은 갱신을 시도합니다. 따라서 업데이트 할 스레드가 스레드 안전 방식으로 처리 될 수 있도록 업데이트하려는 UI 스레드에 알릴 필요가 있습니다. 즉, 스레드를 업데이트하는 백그라운드 스레드가 단순히 비즈니스를 수행 할 수 없으며 개체를 업데이트 할 수있는 권한을 요청해야합니다 UI를 대신하여 객체를 변경하도록 요청할 수 있습니다. 이것은 UI가 개체 업데이트를 처리하는 것을 의미합니다.

답변

1

this old usenet post에 여기에 옵션을 게시했습니다. ThreadedBindingList을 찾으십시오. (대부분의 코드는 예제를 설정하고 있으며, 목록 클래스는 매우 작습니다.);

+0

ThreadedBindingList가 실제로 멋지게 보입니다. 나는 그것을 약간의 시운전에 가져갈 것이라고 생각한다. –

+0

감사합니다. 마크 (Marc) 한 번 보겠습니다. – AndyMM

+0

Marc 님이 UI에서 업데이트를 처리하도록 제안 하시겠습니까? 내 의견을 아래 Yoopergeek에 보냅니다. – AndyMM

0

내 경험이 경우 것이있다 (스레드에서 낮은 업데이트를 놓치지 마세요) ... 그것은 조금 도움이 될 수 있지만, IMO 당신은 단순히 UI는 조금 나중에 업데이트 할 더 잘 할 수있다 UI에 바인드 된 비즈니스 오브젝트가 있으면 해당 오브젝트에 대한 모든 변경 사항이 UI 스레드에서 암시 적으로 수행되어야합니다. 그렇지 않으면 크로스 스레드 예외가 발생합니다.

UI가 아닌 스레드에서 개체를 변경하면 이러한 개체가 UI에 연결되면 나쁜 소식입니다.

예를 들어, 객체가 바인딩 친화적 인 패턴 (예 : INotifyPropertyChanged)을 구현하고 해당 객체 중 하나 또는 다수를 UI에 바인딩하면 막후에서 객체가 이러한 바인딩 친화적 인 이벤트 중 하나가 UI에 과부하가 발생하면 '객체가 변경되었습니다.'라는 알림이 UI 코드로 이동하여 크로스 스레드 예외가 발생합니다.

업데이트 : 업데이트가 비에서 상태를 반대하게되는 경우에 true로 설정 될 수있다 'STFU'개체 수준 변수의 일종을 구현하는 것이 문제가되는 이벤트를 제기 개체를 해결하기 위해 한 가지 방법 -UI 스레드. 그런 다음 "OnRaiseMyEvent (...)"메서드에서 STFU 변수의 상태를 확인할 수 있습니다. 참이면 STFU는 그렇지 않으면 이벤트를 발생시킵니다.

업데이트 # 2 : 아, 질문에 대한 업데이트와 함께 다음과 같은 상황이 발생했습니다. ISynchronizeInvoke을 비즈니스 개체의 생성자에 전달합니다. 그런 다음 비즈니스 객체는 UI 스레드로 이벤트 발생을 마샬링해야하는지 여부를 처리 할 수 ​​있습니다.

public class MyObject { 
    private ISynchronizeInvoke _Invoker; 

    public MyObject(ISynchronizeInvoke invoker) { 
     _Invoker = invoker; 
    } 

    private void OnPropertyChanged(string propertyName) { 
     PropertyChangedEventHandler handlers = this.PropertyChanged; 
     if (handlers != null) { 
     if (_Invoker.InvokeRequired) { 
     _Invoker.Invoke(handlers, new PropertyChangedEventArgs(propertyName)); 
     } else { 
     handlers(new PropertyChangedEventArgs(propertyName); 
     } 
    } 
} 
+0

그게 정확히 문제인지! 이러한 바인딩 친화적 인 인터페이스를 구현하고 있습니다. 그러나 UI에서 비즈니스 객체에 대한 업데이트를 처리하면 캡슐화가 중단됩니다. UI는 모든 권리에 대해 알지 못하는 업데이트를 처리하도록 유도되고 있습니다. – AndyMM

+0

@Mule : "모든 권리에 대해 알지 못하는 업데이트를 UI가 처리하고 있습니다." : 음,하지만 그게 바로 바인딩 인터페이스를 구현하는 이유입니다. . . 그 사건들을 경청하는 것은 UI의 사업이다. – Yoopergeek

+0

@Yoopergeek, 원래 게시물 수정보기 – AndyMM

관련 문제