[英]c# wpf dispatcher.beginInvoke freeze
我正在與服務器通信的應用程序上工作。
thread = new Thread(new ThreadStart(ClientStart));
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
private void ClientStart()
{
tcpClient = new TcpClient(ip,3000);
stream = tcpClient.GetStream();
while (true) {
stream.Read(...);
PrintMessage(...);
.....
}
}
private void PrintMessage(LogWin w, string msg)
{
DateTime dt = DateTime.Now;
w.GetMessageBox().Dispatcher.BeginInvoke(DispatcherPriority.Input,new Action(()=>w.GetMessageBox()
.AppendText(String.Format("{0:d/M/yyyy HH:mm:ss}", dt) + " : " + msg)));
}
稍后我需要將結果打印到消息框。 我知道我必須使用Dispatcher,因為我在另一個線程中工作,但是即使我使用beginInvoke方法,我的應用程序也會凍結。
根據Sheridan的答案進行編輯 :
現在我正在獲取:WindowsBase.dll中發生了類型為'System.InvalidOperationException'的未處理異常
附加信息:調用線程無法訪問該對象,因為另一個線程擁有它。
Dispatcher dispatcher = Dispatcher.CurrentDispatcher;
thread = new Thread(() => ClientStart(dispatcher));
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
private void ClientStart(Dispatcher dispatcher)
{
....
並更改了打印方法:
dispatcher.BeginInvoke(DispatcherPriority.Input, new Action(() =>
w.GetMessageBox()
.AppendText(String.Format("{0:d/M/yyyy HH:mm:ss}", dt) + " : " + msg)));
通過使用Application.Current.Dispatcher
解決
始終要警惕Dispatcher.CurrentDispatcher
因為這將返回用於在CURRENT線程上分派的對象-可能不是UI。 您想要(通常幾乎總是想要)UI線程分派器。
您可以通過Application.Current.Dispatcher
獲得該信息,該Application.Current.Dispatcher
始終返回UI線程分派器。
令人沮喪的是這些調用看起來如此相似...
[如果您在主窗口中,則可以僅致電Dispatcher
但實際情況並非如此]
在MSDN上的Dispatcher.BeginInvoke
方法頁面上:
在WPF中,只有創建
DispatcherObject
的線程才能訪問該對象
因此,如果您首先從后台線程調用Dispatcher
,則它只能在該后台線程上運行。 而是要確保在UI線程上“初始化”您的Dispatcher
對象:
Dispatcher = Dispatcher.CurrentDispatcher;
從MSDN上的Dispatcher
Class頁面:
如果您嘗試獲取當前線程的
CurrentDispatcher
,並且Dispatcher
與該線程未關聯,則將創建一個Dispatcher
。
然后,將對該UI線程Dispatcher
的引用傳遞給您的后台線程,將使您能夠再次從后台線程訪問UI線程。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.