앱은 메인 UI 스레드 (일반적으로 ManagedThreadId==1
)가 있습니다. 일반적으로 채팅 앱에서 이벤트는 다른 스레드 (전용 소켓 수신 스레드 또는 수신 코드의 스레드 풀 스레드)에서 제공됩니다. 다른 스레드에서 끌어 당기는 이벤트에서 UI를 업데이트하려면 디스패처를 사용해야합니다. 여기서 유용한 테스트는 코드가 UI 스레드에 있으면 true를 반환하고 다른 스레드에서는 false를 반환하는 Dispatcher.CheckAccess()
메서드입니다. 메인 창에 있다면
using System.Windows.Threading; // For Dispatcher.
if (Application.Current.Dispatcher.CheckAccess()) {
network_links.Add(new NetworkLinkVM(link, start_node, end_node));
}
else {
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(()=>{
network_links.Add(new NetworkLinkVM(link, start_node, end_node));
}));
}
당신이 사용할 수 있습니다 :
Dispatcher.BeginInvoke(...
당신이 someother 상황에서 경우는 뷰 모델을 예 다음 사용 : 일반적인 호출은 뭔가 보이는
Application.Current.Dispatcher.BeginInvoke(
당신이 원하는 경우에 호출 BeginInvoke 대
사용 Invoke
현재의 thread가 대기하는 UI 스레드까지 UI 스레드에서 작업이 완료 될 때까지 기다리지 않고 현재 스레드를 계속 진행하려는 경우 디스패치 코드 또는 BeginInvoke
을 처리했습니다.
메시지 박스, Dispatcher 및 호출/BeginInvoke : 메시지 박스를 해제 할 때까지
Dispatcher.Invoke
가 스레드를 차단합니다.
Dispatcher.BeginInvoke
은 UI 스레드가 MessageBox 호출을 닫을 때까지 차단하는 동안 스레드 코드가 계속 실행되도록합니다.
CurrentDispatcher 대 Current.Dispatcher!
Dispatcher.CurrentDispatcher
은 현재 UI 스레드가 아닌 현재 스레드에 대한 Dispatcher를 리턴한다는 것을 이해합니다. 일반적으로 UI 스레드의 디스패처에 관심이 있습니까? Application.Current.Dispatcher
항상이 값을 반환합니다.
추가 참고 :
당신은 당신의 checkAccess은 종종 다음 유용한 도우미 메서드는 디스패처를 확인하는 데 찾는 경우
public void DispatchIfNecessary(Action action) {
if (!Dispatcher.CheckAccess())
Dispatcher.Invoke(action);
else
action.Invoke();
}
호출 할 수있는 등 :
DispatchIfNecessary(() => {
network_links.Add(new NetworkLinkVM(link, start_node, end_node));
});
그 의존 ... 그 스레드는 어떤 스레드에서 실행됩니까? 또한, WPF를 사용하고 있는지 확인하십시오. ('Dispatcher'는 그걸로 만 작동합니다.) – svick
어떤 UI 프레임 워크를 사용하고 있습니까?(WinForms, WPF 또는 SL) 그들 사이에 차이가 있습니다 –
그래, svick이 제안하는 것처럼 다른 스레드 (비동기 적으로)에서 UI를 건드리는 경우에 따라 달라집니다 – gideon