use*_*903 1 c# wpf freeze dispatcher
我正在开发一个与服务器通信的应用程序。
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)));
}
Run Code Online (Sandbox Code Playgroud)
稍后我需要将结果打印到消息框。我知道我必须使用 Dispatcher,因为我在另一个线程中工作,但是即使我使用 beginInvoke 方法,我的应用程序也会冻结。
根据谢里丹的回答进行编辑:
现在我得到:WindowsBase.dll 中发生类型为“System.InvalidOperationException”的未处理异常
附加信息:调用线程无法访问此对象,因为其他线程拥有它。
Dispatcher dispatcher = Dispatcher.CurrentDispatcher;
thread = new Thread(() => ClientStart(dispatcher));
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
private void ClientStart(Dispatcher dispatcher)
{
....
Run Code Online (Sandbox Code Playgroud)
并更改了打印方法:
dispatcher.BeginInvoke(DispatcherPriority.Input, new Action(() =>
w.GetMessageBox()
.AppendText(String.Format("{0:d/M/yyyy HH:mm:ss}", dt) + " : " + msg)));
Run Code Online (Sandbox Code Playgroud)
通过使用解决Application.Current.Dispatcher
始终要小心,Dispatcher.CurrentDispatcher因为这将返回一个对象以在 CURRENT 线程上进行调度 - 这可能不是 UI。您想要(并且通常几乎总是想要)UI 线程调度程序。
您可以通过Application.Current.Dispatcher它始终返回 UI 线程调度程序。
令人沮丧的是,这些电话看起来如此相似......
[如果你在主窗口中,你可以打电话,Dispatcher但对你来说可能不是这种情况]