시간과 시간 다시 BindingList 및 ObservableCollection의 스레드 안전 버전을 작성해야하는 이유는 UI에 바인딩 할 때 이러한 컨트롤을 여러 스레드에서 변경할 수 없기 때문입니다. 제가 이해하려고하는 것은 입니다. 이유는 이것이인데, 이것은 설계상의 잘못입니까, 아니면 의도적 인 행동입니까?BindingList 또는 ObservableCollection과 같은 클래스가 스레드로부터 안전하지 않은 이유는 무엇입니까?
답변
스레드 안전 컬렉션 디자인 문제는 간단하지 않습니다. 물론 상태를 손상시키지 않고 여러 스레드에서 수정하거나 읽을 수있는 컬렉션을 디자인하는 것은 간단합니다. 그러나 여러 스레드에서 업데이트되면 주어진 컬렉션을 디자인하는 것이 훨씬 어렵습니다. 다음 코드를 예로 들어 보겠습니다.
if (myCollection.Count > 0) {
var x = myCollection[0];
}
myCollection은 추가 및 업데이트로 상태가 손상되지 않도록 보장되는 스레드 안전 수집이라고 가정합니다. 이 코드는 스레드로부터 안전하지 않으며 경쟁 조건입니다.
왜? myCollection이 안전하더라도 myCollection : namedly와 indexer의 두 메서드 호출간에 변경이 발생하지 않는다고 보장 할 수 없습니다. 다른 스레드가 들어 와서이 호출 사이의 모든 요소를 제거 할 수 있습니다.
이 유형의 문제는 매우 솔직히 악몽입니다. 한 호출의 반환 값이 콜렉션의 후속 호출에 영향을 줄 수는 없습니다. http://blogs.msdn.com/jaredpar/archive/2009/02/11/why-are-thread-safe-collections-so-hard.aspx
야렛의 훌륭한 대답에 약간을 추가하려면 : 스레드 안전을 무료로 제공되지 않습니다
편집
나는 최근 블로그 게시물에서이 토론을 확장했다. 많은 (대부분?) 컬렉션은 단일 스레드에서만 사용됩니다. 멀티 스레드 케이스를 처리하기 위해 성능 또는 기능상의 불이익을받는 이유는 무엇입니까?
글쎄, 어쩌면 나는 그것을 다음과 같이 바꿔야한다. 왜 프레임 워크가 ThreadSafeObservableCollection 또는 그와 같은 것을 제공하지 않는가? –
그건 좀 더 합리적인 질문입니다.하지만 Jared의 대답이 시작됩니다. 이것은 정말로 "thread-safe"가 의미하는 것에 달려 있습니다. 이것은 간단한 yes/no 플래그가 아닙니다. –
, 나는 이것이 당신의 문제를 해결하는 가장 간단한 방법이라고 생각 "왜 제정신 클래스 X 아니다"
을
에 "클래스 X와 함께이 일의 온건 한 방법은 무엇입니까?" 당신이 당신의 관찰 컬렉션을 만들 때 클래스의 생성자에서
는 현재 displatcher를 얻을. 당신이 지적한대로 원래 스레드에서 수정이 필요합니다. 메인 GUI 스레드가 아닐 수도 있습니다. 그래서 App.Current.Dispatcher은 올바르게 작동하지 않으며 이며 모든 클래스가 입니다 .Dispatcher.
_dispatcher = System.Windows.Threading.Dispatcher.CurrentDispatcher; _data = new ObservableCollection<MyDataItemClass>();
- 는 코드 섹션 원래 스레드를 필요 를 호출하는 발송자를 사용합니다. 당신을 위해 트릭을 할해야
_dispatcher.Invoke(new Action(() => { _data.Add(dataItem); }));
. 상황이 있지만 을 선호 할 수도 있습니다. 대신 .BeginInvoke .Invoke을 입력하십시오.
- 1. 스레드 안전하지 않은 java 클래스가 추가 된 이유는 무엇입니까?
- 2. std :: queue :: empty()가 스레드로부터 안전하지 않은 이유는 무엇입니까? 함수를 스레드로부터 보호해야하지 않습니까?
- 3. 엔티티 관리자가 컨테이너 관리에서 스레드 안전하지 않은 이유는 무엇입니까?
- 4. 이벤트 핸들러는 스레드로부터 안전하지 않습니까?
- 5. 자바 스크립트에서 eval이 안전하지 않은 이유는 무엇입니까?
- 6. List <T>이 스레드로부터 안전하지 않은 이유는 무엇입니까? 다음 사이트에서
- 7. CoreData가 의미하는 바는 스레드로부터 안전하지 않습니까?
- 8. .NET에는 스레드로부터 안전한 일반 클래스가 있습니까?
- 9. Java의 Method 클래스가 일반적이지 않은 이유는 무엇입니까?
- 10. Android의 안전하지 않은 클래스입니까?
- 11. 고정 크기 버퍼 (배열)가 안전하지 않은 이유는 무엇입니까?
- 12. - 안전하지 않은 코드, IntPtr입니다
- 13. MVC Razor ViewEngine은 스레드로부터 안전하지 않습니까?
- 14. 안전하지 않은 일반적인 캐스트
- 15. 스레딩 및 안전하지 않은 변수
- 16. 반복되는 시퀀스를 수정하는 것이 안전하지 않은 이유는 무엇입니까?
- 17. 반복기 컨텍스트에서 안전하지 않은 키워드를 사용할 수없는 이유는 무엇입니까?
- 18. 계속 statement를 사용하는 것이 안전하지 않은 이유는 무엇입니까?
- 19. "strcat"이 "안전하지 않은"것으로 간주되는 이유는 무엇입니까?
- 20. op-assign 연산자가 java에서 안전하지 않은 이유는 무엇입니까?
- 21. Sec-WebSocket-Key1이없는 WebSockets이 안전하지 않은 이유는 무엇입니까?
- 22. ReaderWriterLockSlim을 사용하여 내 사전 스레드가 안전하지 않은 이유는 무엇입니까?
- 23. JSLint "안전하지 않은 문자"
- 24. 안전하지 않은 방식으로 Uploadify
- 25. 안전하지 않은 Crytographic 시스템
- 26. 안전하지 않은 '^'jshint 문제
- 27. 여기에 검사되지 않고 안전하지 않은 작업은 무엇입니까?
- 28. 스레드로 안전하지 않은 부분적으로 구성된 객체
- 29. IIS에서 싱글 톤 클래스가 스레드로부터 안전한가요?
- 30. 인터페이스 또는 추상 클래스가 유용한 이유는 무엇입니까? (또는 무엇을?)
나는 똑같은 문제가 있습니다. Dispatcher 나 다른 방법을 사용하여 백그라운드 스레드에서 BindingList에 항목을 추가하려면 어떻게합니까? – Houman
예, 간단히 말해서 .NET 콜렉션 * 인터페이스 자체의 디자인은 스레드 안전성에 적합하지 않습니다. Jared가 지적한 것처럼 Count 속성은 멀티 스레드 환경에서는 쓸모가 없습니다. –
스레드 안전 형식으로 구현 될 수있는 'IList'기능의 많은 유용한 하위 집합이 있습니다. 물건을 제거하거나 주변을 움직이는 항목은 문제가 될 수 있지만 나머지 인터페이스는 많은 응용 프로그램에서 유용한 하위 집합이됩니다. 추가 된 항목의 색인을보고 한 '추가'버전이 도움이 될 수 있지만 모든 응용 프로그램이 필요하지는 않습니다. 추가 된 모든 항목이 목록 수명 동안 동일한 슬롯에 계속 존재한다면 스레드 안전 'IList '구현은 외부 잠금이없는 많은 멀티 스레드 시나리오에서 유용 할 수 있습니다. –
supercat