2011-10-19 54 views
3

我有一个用户控件添加到我的主窗口。主代码不断接收TCP消息并相应地与UserControl交互。其中一个用户控件的方法是由主称为是方法addMessage:线程无法访问对象

internal void AddMessage(Paragraph p) 
{ 
    if (txtViewer.Dispatcher.CheckAccess()) 
    { 
     txtViewer.Document.Blocks.Add(p); 
    } 
    else 
    { 
     Dispatcher.Invoke(new Action(() => 
      { 
       txtViewer.Document.Blocks.Add(p); 
      } 
     )); 
    } 
} 

内Dispatcher.Invoke线总是引发InvalidOperationException。我环顾了类似的问题,其中大多数是Dispatcher未被使用的情况,所以我不知道为什么我的代码无法工作。我想我错误地使用它,或者它可能与线程之间传递的段落对象有关。

感谢, 贾里德

+0

您是否尝试在UI线程中调用'AddMessage'(=而不调用Dispatcher.Invoke')以查看是否有与线程无关的错误? –

+0

使用BeginInvoke而不是Invoke。 – Candide

+2

我不是这方面的专家。我有一个类似的问题,无法绑定从Dispatcher派生的FlowDocument的DocumentViewer异步。用户界面无法与另一个调度器上派生的对象通信。我必须使用XamlWriter.Save将FlowDocument序列化为字符串(不派生自调度程序),然后在Converter中对其进行反序列化。 – Paparazzi

回答

1

我有一个类似的问题,无法绑定从Dispatcher派生的FlowDocument的DocumentViewer异步。该UI无法绑定到派生于另一个上的分派器的对象。我必须使用XamlWriter.Save将FlowDocument序列化为字符串(不派生自调度程序),然后在Converter中对其进行反序列化。

+0

我最终将IsAsynch = true转换为BackgroundWorker并获得了10倍的性能提升。在序列化和反序列化中有很多开销,并且你失去了调度程序的好处。而且你也获得了取消的能力。 IsAsynch = true最适合返回小字符串的昂贵任务。 – Paparazzi

0

它可能有一些做的对象被冻结。

对象自Freezable导出的想法是,它通常是在读 /写状态,但可以使用冷冻方法被明确地放入只读 状态。在WPF中可以更有效地使用冻结的对象,因为它不需要通知消费者该对象的值已更改。

WPF中的图形对象(如刷子和3D几何图形)来自 Freezable。最初解冻后,对这些对象之一进行更改会导致通知消费者更改此对象。

如果您有一个派生自Freezable的对象,而您不打算更改 ,则可以使用Freeze方法使该对象为只读。

冻结对象后,如果您尝试修改它,您将得到一个InvalidOperationException。但WPF将 更有效地使用该对象。

取自这里:

http://wpf.2000things.com/tag/freezable/

1

您检查的txtViewerDispatcher的访问,但一些其他Dispatcher调用如果CheckAccess失败了,你什么都不知道说Dispatcher。您想改用txtViewer.Dispatcher来调用。

+0

我做了这个改变,错误仍然发生。 – Jared

+0

@Jared:什么是异常消息?有没有内部的例外,如果是的话,他们说什么? –

+0

InvalidOperationException:调用线程无法访问此对象,因为不同的线程拥有它。 没有内部例外。 – Jared