0

다음은 내 문제입니다. SortableCollection : ObservableCollection을 만들었습니다. 및 정렬 방법 (색상 정렬)이 추가되었습니다. 주 스레드를 사용하여 컬렉션을 정렬 할 때 모든 것이 잘 작동하고 작동합니다. 하지만 컬렉션에있는 항목을 사용하여이 customCollection을 정렬하려고하면 필자는 다음과 같은 이유로이 개체에 액세스 할 수 없습니다. 다른 스레드가 소유 함). 웹에서 살펴본 결과 몇 가지 해결책을 찾았습니다. One SolutionobservableCollection을 만드는 방법

이 유형의 솔루션은 삽입을 위해 다중 스레드를 수집하여 이동 작업을 제거합니다. 하지만 사용자 지정 정렬이 아닙니다. 도움을 주셔서 감사합니다.

답변

0

WPF 클래스에는 스레드 선호도가 있습니다. 이것이 의미하는 바는 해당 객체에 대한 모든 변경 사항이 작성된 동일한 스레드에 있어야한다는 것입니다. 스레드 세이프 (thread-safe) 인 사용자 인터페이스 API를 만드는 것은 진정으로 어렵습니다. 따라서 Microsoft는이 스레드를 단일 스레드로 유지하고 런타임 확인을 통해 강제로이를 확인했습니다.

그렇다면 백그라운드 스레드에서 정렬을 수행하고 UI 스레드에서 적용해야하는 몇 가지 옵션이 있습니다. 첫 번째 옵션은 SortableCollection을 일반 오래된 목록 또는 배열에 복사하고 백그라운드에서 정렬을 수행하는 것입니다. 백그라운드 스레드가 완료되면 Dispatcher를 사용하여 UI 스레드에서 코드를 실행합니다. WPF의 모든 UI 요소는 System.Windows.Threading.DispatcherObject까지 확장되고 대부분은 System.Windows.Freezable까지 확장됩니다. DispatcherObject는 UI 스레드에서 코드를 실행하도록 Dispatcher를 가져 오는 곳입니다.

논리적으로, 실행이 같은 것입니다 :

public void BackgroundSort() 
{ 
    List<T> items = new List<T>(this.ToArray()); 
    BackgroundSortDelegate del = Sort; 

    del.BeginInvoke(SortCompleted, del); 
} 

private void SortCompleted(IAsyncResult result) 
{ 
    BackgroundSortDelegate del = result.AsyncState as BackgroundSortDelegate; 

    List<T> items = del.EndInvoke(result); 
    this.Dispatcher.Invoke(()=>{this.Collection = items;}); 
} 

무슨 일이 있었는지의 간단한 설명이 백그라운드 작업자/위임이 목록의 항목의 복사본을 사용하고 있다는 점이다. 정렬이 완료되면 Dispatcher 객체를 호출하고 액션을 호출합니다. 그 작업에서 우리는 새 정렬 된 목록을 다시 객체에 할당합니다.

UI 스레드 내에서 백그라운드 작업의 결과를 할당하는 핵심은 UI의 Dispatcher 객체를 사용하는 것입니다. 실제로 C#에서 백그라운드 작업자를 호출하는 방법은 여섯 가지가 있지만 백그라운드 스레드에서 UI 스레드로 작업하는 방법은 동일합니다.

+0

설명해 주셔서 감사합니다. 하지만이 방법을 어디에 써야하나요? sortableCollection 또는 sorting 메서드를 선언하는 이벤트 처리기에서? – Khaldoun

+0

논리적으로 가장 이해가되는 곳이면 어디든. SortableCollection에서이 작업을 수행하면 SortableCollection 만 다른 메서드에 전달할 수 있고 자동으로 상호 작용할 수 있다는 이점이 있습니다. 경고 메시지 : Dispatcher는 값 비싼 작업입니다. 가끔씩 불리는 것은 괜찮지 만, 단단한 루프에서는 정말 느려질 것입니다. –

관련 문제