Создание System.Windows.Controls.Image вызывает исключение - как мне использовать диспетчер для его создания? - PullRequest
4 голосов
/ 09 июня 2010

Я запускаю свои модульные тесты на фрагменте кода, который выполняет следующее в тесте:

Assert.IsNotNull(target.Icon);

Внутри геттера для свойства Icon я делаю это:

System.Windows.Controls.Image img = new System.Windows.Controls.Image();

Вот это исключение: System.InvalidOperationException: вызывающий поток должен быть STA, потому что это требуется для многих компонентов пользовательского интерфейса.

Я понимаю, что это значит, и понимаю, что мне нужно использовать Dispatcher, но я немного озадачен тем, как и почему ... это свойство моей ViewModel, и я не получаю ничего исключения при запуске приложения.

Другая информация: сбой начинался только при обновлении до .NET 4.

Ответы [ 4 ]

1 голос
/ 09 июня 2010

Поток, выполняющий модульное тестирование, не является потоком STA, вы создаете поток STA следующим образом:

Thread backgroundThread;
backgroundThread = new Thread(DoWork);
backgroundThread.SetApartmentState(ApartmentState.STA);
backgroundThread.Start();

Я не знаю, какую платформу модульного тестирования вы используете и как изменить ее потокмодель, но вам нужно как-то вызвать Thread.SetApartmentState перед Thread.Start, чтобы это работало.

«Состояние квартиры» - это вещь COM, она требуется WPF, потому что (как говорят ошибки) многие элементы управления WPFтребовать COM, с потоком STA автоматически не связан диспетчер.

Обычно вам не нужно беспокоиться о диспетчере, система создаст его при необходимости.

В случае, если вам нужно создать диспетчер для потока, вы можете просто прочитать Dispacher.CurrentDispacher - но вы не сможете сделать что-либо значимое с этим диспетчером, если не позволите ему управлять потоком (вызывая Dispacher.run).

1 голос
/ 09 июня 2010

Проблема здесь в том, что вы выполняете модульное тестирование WPF, для работы которого требуется STA, а среда модульного тестирования использует MTA.Для запуска тестов в STA вам необходимо настроить среду модульного тестирования.

Каждый фреймворк имеет свой способ сделать это.Обычно вы можете найти его, просто введя название платформы тестирования и STA в Google.

0 голосов
/ 09 июня 2010

Я думаю, что вам, возможно, придется немного изменить свой подход. Я думаю, что вам нужно будет изменить вашу ViewModel так, чтобы вы выставляли URI изображения, а не элемент управления Image.

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

0 голосов
/ 09 июня 2010

Используете ли вы какой-либо другой поток не-пользовательский интерфейс? Если так, вы уверены, что они не имеют доступа к этой собственности? Проверьте, используете ли вы какие-либо компоненты в платформе, которая использует поток или работает асинхронно (например, FileSystemWatcher), которые могут использовать это свойство. Однако поможет еще немного кода.

...