Поток не может получить доступ к объекту - PullRequest
3 голосов
/ 19 октября 2011

У меня есть UserControl, который добавляется в главное окно.Основной код постоянно получает TCP-сообщения и соответственно взаимодействует с UserControl.Одним из методов UserControl, который вызывается Main, является 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 не использовался, поэтому я не знаю, почему мой код не работает.Я полагаю, что я использую его неправильно, или это может быть связано с тем, что объект Paragraph передается между потоками.

Спасибо, Джаред

Ответы [ 3 ]

1 голос
/ 19 октября 2011

Вы проверяете доступ на Dispatcher из txtViewer, но вызываете на некоторых других Dispatcher, если CheckAccess не удается, вы ничего не знаете о сказанном Dispatcher. Вместо этого вы хотите вызвать txtViewer.Dispatcher.

1 голос
/ 21 октября 2011

У меня была похожая проблема: я не смог связать асинхронность DocumentViewer с FlowDocument, полученным из Dispatcher. Пользовательский интерфейс не может привязаться к объекту, производному от Dispatcher в другой группе. Мне пришлось сериализовать FlowDocument в строку (не выводится из диспетчера) с использованием XamlWriter.Save, а затем десериализовать в конвертере.

0 голосов
/ 19 октября 2011

Это может иметь какое-то отношение к замороженному объекту.

Идея объекта, производного от Freezable, заключается в том, что он обычно находится в состоянии чтения / записи, но может быть явно помещен всостояние только для чтения с использованием метода Freeze.Замороженный объект можно более эффективно использовать в WPF, поскольку ему не нужно уведомлять потребителей об объекте об изменении его значения.

Графические объекты в WPF, такие как кисти и трехмерные геометрии, получены из Freezable.Изначально при размораживании изменение одного из этих объектов приводит к тому, что потребители объектов уведомляются об изменении.

Если у вас есть объект, производный от Freezable, который вы не планируете изменять, вы можете сделать объекттолько для чтения с использованием метода Freeze.

После замораживания объекта, если вы попытаетесь изменить его, вы получите InvalidOperationException.Но WPF будет более эффективно использовать объект.

Взято отсюда:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...