【发布时间】:2014-05-22 12:38:32
【问题描述】:
我正在开发一个与服务器通信的应用程序。
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
【问题讨论】:
-
我相信在 MessageBox 上打印不需要调用 UI
-
调度程序线程就是这样 - 一个线程。它只能按顺序处理事物。如果您调用 Dispatcher.Invoke,那么您的委托将被添加到队列中并根据优先级进行处理。这意味着在处理您的委托时,Dispatcher 将无法发送消息,因此您的 UI 将被锁定。
-
stream.Read 需要多长时间才能完成?您的 while(true) 语句有一个紧密的循环,因此您可能没有提供足够的资源来允许消息泵运行。
标签: c# wpf freeze dispatcher