디자인 패턴을 위한 멀티 스레드 관찰
-
09-06-2019 - |
문제
디지털 신호 수집 시스템에서 수시로 데이터를 밀어넣으로 관찰자의 시스템에 의해 하나의 스레드가 있습니다.
예제에서 Wikipedia/Observer_pattern:
foreach (IObserver observer in observers)
observer.Update(message);
할 때 예를 들어,사용자 작업에서 예:GUI-실 필요한 데이터를 중지에 흐르는,당신은 휴식을 주는 관찰자 연결,그리고 심지어는 처분하는 관찰자 alltogether.
한 주장 할 수 있다:을 중지해야로 데이터 소스를 기다립 sentinel 값의 처리 연결입니다.그러나 그것이 부과 대기 시간에는 시스템입니다.
의 경우 물론,데이터 펌프레드는 단지 요청에 대한 주소는 관찰자의,그것은 그것을 찾을 수 있습의 메시지를 보내는 파괴 개체입니다.
은 사람이 만들었는'공식'디자인 패턴을 반대 이 상황입니까?안 그들은?
해결책
하려는 경우 데이터 원본을 항상 안전 측면에서의 동시성 당신이 있어야에서는 적어도 하나의 포인터는 항상 안전하는 그를 위해 사용합니다.그래서 관찰자가 객체가 있어야 하는 수명 종료 되지 않습기 전에는 데이터의 근원이다.
여 이 작업을 수행할 수 있습만 추가하는 관찰자들,그러나 결코 제거 할 수 있습니다.할 수 있는 각 관찰하지 않는 핵심 구현을 자체,그러나 그것은 대리인 이 작업에는 ObserverImpl 개체입니다.당신은 잠금 액세스를 이 impl 개체입니다.이는 더 큰 문제가 없다,그것은 단지 GUI unsubscriber 것이 차단되는 경우에는 관찰자는 바쁜 사용하여 ObserverImpl 개체입니다.는 경우 GUI 응답 것이 문제가 될 사용할 수 있습니다 몇 가지 종류의 동시 작업 큐 메커니즘과 함께 탈퇴 작업 부분에 표시됩니다.(다음과 같 PostMessage Windows)
구독 해제할 때,당신은 단지 대체에 대한 핵심 구현미 구현합니다.다시 작업을 잡고 있습니다.이것은 참으로 소개하는 몇 가지 기다리고 있는 데이터 소스하지만,때문에 그것은 단지[lock-포인터를 스왑-의 잠금을 해제]당신이 말할 수 있는 것이 충분히 빠르게 실시간 응용 프로그램.
만약 당신이 피하고 싶은 겹쳐 쌓이는 관찰자는 개체를 포함하고 있는 더미,당신이해야 할 몇 가지 종류의 회계이지만,이 수 졸가 사소한 개체처럼 들고 포인터를 관찰자에게 그 개체에서 필요한 목록입니다.
최적화:는 경우에 당신은 또한 당신을 유지 구현이(진짜+더미)살아있는 한 관찰자 자체,당신이 할 수있지 않고 실제 자물쇠와 같은 것을 사용 InterlockedExchangePointer 을 교환하는 포인터입니다.최악의 경우 시나리오:위임하는 전화가 진행하는 동안 포인터가 교환-->더 큰 문제는 모든 개체가 살아있고 위임를 계속할 수 있습니다.다음 위임하는 통화가 될 것이 새로운 구현 객체입니다.(제외하고 모든 새로운 스왑 물론)
다른 팁
당신에게 메시지를 보낼 수 있다 모든 관계자 그들을 알리는 데이터 소스를 종료하고 관계자를 제거에서 자신의 목록입니다.
에 응하여 의견의 구현 과목 관찰자의 패턴을 허용해야에 대한 동 추가/제거의 관찰자입니다.C#,이벤트 시스템은 주제/관찰자의 패턴에는 관찰자를 사용하여 추가 event += observer
을 사용하여 제거 event -= observer
.