c#wpf dispatcher.beginInvoke freeze

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

Ric*_*bob 5

始终要小心,Dispatcher.CurrentDispatcher因为这将返回一个对象以在 CURRENT 线程上进行调度 - 这可能不是 UI。您想要(并且通常几乎总是想要)UI 线程调度程序。

您可以通过Application.Current.Dispatcher它始终返回 UI 线程调度程序。

令人沮丧的是,这些电话看起来如此相似......

[如果你在主窗口中,你可以打电话,Dispatcher但对你来说可能不是这种情况]