InvalidOperationException для объекта из потока, который сделан - PullRequest
2 голосов
/ 30 октября 2009

В приложении WPF у меня был поток BackgroundWorker, создающий объект. Давайте назовем объект foo.

Код рабочего фона:

SomeClass foo = new SomeClass();
// Do some operation on foo

// Set some dependency property on the main class to foo
this.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
    (SendOrPostCallback)delegate { SetValue(FooProperty, foo); },
    foo);

Теперь, когда основной класс пытается получить доступ к FooProperty с помощью метода получения, я получаю исключение InvalidOperationException: вызывающий поток не может получить доступ к этому объекту, поскольку он принадлежит другому потоку.

Если поток создания объекта закончен, почему он все еще владеет объектом? Есть ли где-нибудь вокруг этого?

Ответы [ 3 ]

2 голосов
/ 30 октября 2009

Объект, который вы создаете в данном потоке, принадлежит этому потоку. Вот почему вы получаете InvalidOperationException. Если вы хотите установить свойство в фоновом потоке, я рекомендую делегату вернуть желаемое значение и вызвать SetValue из вашего основного потока. (поток, создавший объект).

1 голос
/ 30 октября 2009

Предполагая, что SomeClass является производным от DispatcherObject, созданный им поток запускает насос сообщений, который отвечает за обработку сообщений для объекта foo. Поэтому, если этот поток заканчивается, объект больше не может обрабатывать сообщения, что не очень хорошая идея.

В большинстве случаев вы должны использовать один и тот же поток пользовательского интерфейса для создания всех ваших объектов пользовательского интерфейса (или чего-либо еще, полученного из DispatcherObject и убедиться, что он работает в течение всего времени вашего приложения. Затем используйте Dispatcher для отправлять ему сообщения из ваших рабочих тем.

1 голос
/ 30 октября 2009

Подавляющее большинство объектов в WPF имеют сходство потоков. Когда-то созданный в определенном потоке, объект WPF будет работать только при использовании из этого потока. Это ограничение применяется (в отличие от WinForms) практически к каждой операции, которую вы выполняете над этим объектом.

Вам потребуется изменить код, чтобы Foo создавался в реальном потоке пользовательского интерфейса для этого сценария.

...