2009-10-06 3 views
2

이벤트 로깅을위한 클래스를 작성하고 있습니다. 내 LogClass는 싱글 톤으로 구현되며 시스템의 모든 클래스는 로그 항목을 작성할 수 있습니다. 항목은 List에 저장되고 버퍼가 가득 차면 디스크에 덤프됩니다.C에서 DataGridView 및 BindingList를 사용할 때의 스레드 안전 조언

DataGridView를 사용하여 실행하는 동안 LogClass의 내용을 표시하므로 뷰어가 자동으로 업데이트되도록 BindingList를 사용했습니다.

내 수업이 스레드 안전성이 얼마나 좋은지 궁금합니다. 목록에 새 항목을 추가 할 때마다 그리고 목록을 반복하여 디스크에 덤프 할 때마다 "잠금"이 사용됩니다. DataGridView 외에도 클래스는 기본적으로 쓰기 전용입니다. 로그에서 읽는 옵션이 없기 때문에 로그에 엔트리를 추가하기 위해서입니다. 덤프는 내부적으로 실행되며 BindingList에 대한 명시 적 읽기 명령이있는 유일한 경우입니다.

내 관심사는 DataGridView와 BindingList를 계속 사용하는 것입니다. BindingList는 목록이 변경 될 때마다 이벤트를 발생시킵니다. 새 항목을 추가 할 때 문제가되는 것처럼 보이지 않습니다. 추가가 완료되면 이벤트가 throw되기 때문입니다.

덤프에 대한 나의 코드()이다 : 나는 전체를 반복하는 동안 목록을 고정하고있어 비록

lock (lockObj) { 
    foreach (LogEntry le in List) { 
     writeToDisk(le) 
     removeFromList(le) 
    } 
} 

, 이벤트 목록 (때문에 제거)으로 변경 뷰어에 발생합니다 및 따라서 DataGridView에서 읽습니다. 나는 그것을 바꾸는 동안 정말로 목록에 읽거나 쓰는 것을 원하지 않는다. 아이디어가 있으십니까?

+0

http://stackoverflow.com/questions/1351138/bindinglist-listchanged-event –

+0

http://stackoverflow.com/questions/1351138/bindinglist-listchanged-event –

답변

1

은 정말 문제가되지이다 일단 바인딩되면 Form.Invoke 메서드 (Control.Invoke에서 상 속됨)에서만 목록을 변경할 수 있기 때문입니다. 다른 스레드에서 목록을 변경하려고하면 .NET 런타임은 "현재 스레드에서이 목록을 변경할 수 없습니다"와 같은 예외를 표시하는 예외에서 짖어 내릴 것입니다.

This에는 잡을 수있는 코드가 있습니다.

감사합니다, = 앨런

1

BindingList가 변경 알림을 구현하지 않았다고 생각했습니다. 이 시나리오에서는 스레드 안전하다고 생각하지 않습니다.

해결 방법은 IBindingList를 구현하는 사용자 지정 컬렉션을 사용하고 요소를 반환하기 전에 목록 접근자를 변경하여 잠금을 획득하는 것일 수 있습니다. 당신이 원한다면 나는이 공유 할 수 있도록

나는 변경 알림과 IBindingList의 사용자 지정 구현을 가지고있다. (아마 어쨌든 구현을 설명하는 코드 프로젝트에 대한 기사를 쓸 것이다 ..)