线程无法访问对象

时间:2011-10-19 15:47:23

标签: c# wpf multithreading

我有一个添加到主窗口的UserControl。主代码不断接收TCP消息并相应地与UserControl交互。 Main调用的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。我查看了类似的问题,其中大部分是调度程序未被使用的情况,所以我不知道为什么我的代码不起作用。我想我错误地使用它,或者它可能与在线程之间传递的Paragraph对象有关。

谢谢, 贾里德

3 个答案:

答案 0 :(得分:1)

您检查Dispatcher的{​​{1}}上的访问权限,但如果txtViewer失败则会调用某些其他 Dispatcher,您对此一无所知说CheckAccess。您想要在Dispatcher上调用。

答案 1 :(得分:1)

我遇到了类似的问题,无法将DocumentViewer asynch绑定为派生自Dispatcher的FlowDocument。 UI无法绑定到另一个thead上从Dispatcher派生的对象。我不得不使用XamlWriter.Save将FlowDocument序列化为字符串(不是从调度程序派生),然后在转换器中反序列化。

答案 2 :(得分:0)

它可能与被冻结的对象有关。

  

从Freezable派生的对象的想法是它通常是   处于读/写状态,但可以显式放入只读状态   使用Freeze方法的状态。可以使用更多的冻结对象   在WPF中有效,因为它不需要通知消费者   对象,它的值已经改变。

     

WPF中的图形对象(如画笔和3D几何图形)派生自   可冻结。最初解冻,改变其中一个对象   导致对象的消费者被告知变化。

     

如果您有一个源自Freezable的对象,那么您不打算这样做   更改,您可以使用Freeze方法将对象设为只读。

     

冻结物体后,如果你试试   修改它,你会得到一个InvalidOperationException。但WPF会   在使用对象时更有效率。

从这里采取:

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