[C#] 다른 스레드가 이 개체를 소유하고 있어 호출한 스레드가 해당 개체에 액세스할 수 없습니다.

'System.InvalidOperationException' 형식의 예외가 WindowsBase.dll에서 발생했지만 사용자 코드에서 처리되지 않았습니다.
추가 정보: 다른 스레드가 이 개체를 소유하고 있어 호출한 스레드가 해당 개체에 액세스할 수 없습니다.

다른 스레드가 이 개체를 소유하고 있어 호출한 스레드가 해당 개체에 액세스할 수 없습니다

오류 현상은 보통, View 스레드에서 이 개체를 소유하고 있기 때문에 호출한 스레드가 개체에 액세스할 수 없어서 발생합니다.

해당 예제 소스는 WPF에서 비동기 이벤트 핸들러(델리게이트)에서 발생하도록 구현한 예제입니다. 해당 Text 객체에 접근을 시도하여 오류가 발생합니다.

//args는 LoadingStateChangedEventArgs 매개변수입니다.

args.Browser.GetSourceAsync().ContinueWith(taskHtml => {
    txt.Text = result;
});

다음은 동기적으로 실행하여 해결하는 예제자료입니다.

//
// 요약:
//     Executes the specified delegate synchronously at the specified priority on the
//     thread on which the System.Windows.Threading.Dispatcher is associated with.
//
// 매개 변수:
//   priority:
//     The priority, relative to the other pending operations in the System.Windows.Threading.Dispatcher
//     event queue, the specified method is invoked.
//
//   method:
//     A delegate to a method that takes no arguments, which is pushed onto the System.Windows.Threading.Dispatcher
//     event queue.
//
// 반환 값:
//     The return value from the delegate being invoked or null if the delegate has
//     no return value.
//
// 예외:
//   T:System.ArgumentException:
//     priority is equal to System.Windows.Threading.DispatcherPriority.Inactive.
//
//   T:System.ComponentModel.InvalidEnumArgumentException:
//     priority is not a valid priority.
//
//   T:System.ArgumentNullException:
//     method is null.

args.Browser.GetSourceAsync().ContinueWith(taskHtml => {
    Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate {
        txt.Text = result;
    }));
});

Dispatcher를 통해 해당 개체에 액세스하는 방법 예시는 다음과 같습니다. 위에서 언급한 예제는 html이기 때문에 더  자주 사용할 수 있는 디스패처에 대해 안내해드리겠습니다~ dispatch는 보냄, 발송, 파견을 뜻합니다. 뷰 또는 메인 스레드에서만 디자이너에 액세스가 가능하기 때문에, 이를 관리하는 디스패처에게 UI 설정을 요청하는 것이지요.

Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate
{
    Topmost = true;
}));

댓글