Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c#wpf dispatcher.beginInvoke冻结_C#_Wpf_Freeze_Dispatcher - Fatal编程技术网

c#wpf dispatcher.beginInvoke冻结

c#wpf dispatcher.beginInvoke冻结,c#,wpf,freeze,dispatcher,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 = tcpCli

我正在开发一个与服务器通信的应用程序

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)));

}
稍后,我需要将结果打印到messagebox。我知道我必须使用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)
    { 
....
并更改了打印方法:

 dispatcher.BeginInvoke(DispatcherPriority.Input, new Action(() =>
       w.GetMessageBox()
            .AppendText(String.Format("{0:d/M/yyyy HH:mm:ss}", dt) + " : " + msg)));
使用MSDN上的页面中的
应用程序.Current.Dispatcher
解决

在WPF中,只有创建
DispatcherObject
的线程才能访问该对象

因此,如果首先从后台线程调用
调度程序
,那么它只能在该后台线程上运行。相反,请确保“初始化”UI线程上的
Dispatcher
对象:

Dispatcher = Dispatcher.CurrentDispatcher;
从MSDN上的页面:

如果尝试获取当前线程的
CurrentDispatcher
,并且
Dispatcher
未与该线程关联,则将创建
Dispatcher

然后,将对该UI线程的引用
Dispatcher
传递到后台线程将使您能够从后台线程再次访问该UI线程。

从MSDN上的页面:

在WPF中,只有创建
DispatcherObject
的线程才能访问该对象

因此,如果首先从后台线程调用
调度程序
,那么它只能在该后台线程上运行。相反,请确保“初始化”UI线程上的
Dispatcher
对象:

Dispatcher = Dispatcher.CurrentDispatcher;
从MSDN上的页面:

如果尝试获取当前线程的
CurrentDispatcher
,并且
Dispatcher
未与该线程关联,则将创建
Dispatcher


然后,将对该UI线程的引用
Dispatcher
传递到后台线程将使您能够从后台线程再次访问UI线程。

始终要小心
Dispatcher.CurrentDispatcher
,因为这将返回一个对象,以便在当前线程上进行调度,而该对象可能不是UI。您需要(通常几乎总是需要)UI线程调度程序

您可以通过
Application.Current.Dispatcher
获得它,它总是返回UI线程调度程序

很遗憾这些电话看起来很相似


[如果您在主窗口中,您可以直接调用
Dispatcher
,但这可能不是您的情况]

始终要小心
Dispatcher.CurrentDispatcher
,因为这将返回一个对象,以便在当前线程上进行调度,而该对象可能不是UI。您需要(通常几乎总是需要)UI线程调度程序

您可以通过
Application.Current.Dispatcher
获得它,它总是返回UI线程调度程序

很遗憾这些电话看起来很相似


[如果您在主窗口中,您可以直接调用
Dispatcher
,但这可能不是您的情况]

我相信在MessageBox上打印不需要调用UIT Dispatcher线程只是一个线程。它只能按顺序处理事情。如果调用Dispatcher.Invoke,那么您的委托将被添加到队列中,并根据优先级进行处理。这意味着,在处理您的委托时,调度程序将无法发送消息,因此您的UI将被锁定。stream.Read需要多长时间才能完成?while(true)语句的循环很紧,因此您可能无法提供足够的资源来运行消息泵。我相信在MessageBox上打印并不需要调用UIT。dispatcher线程只是一个线程。它只能按顺序处理事情。如果调用Dispatcher.Invoke,那么您的委托将被添加到队列中,并根据优先级进行处理。这意味着,在处理您的委托时,调度程序将无法发送消息,因此您的UI将被锁定。stream.Read需要多长时间才能完成?while(true)语句的循环很紧,因此您可能无法产生足够的资源来运行消息泵。