Как часть переноса моего приложения на .NET 4, я изо всех сил пытаюсь вернуть некоторые модульные тесты WPF снова с TeamCity.Почему я получаю Invalid Operation Exception (не STA-поток?), Выполняющий этот тест MSpec на TeamCity?
На всех тестах, которые каким-то образом с помощью элемента управления WPF (а ListItem, например), я получаю исключение я не получал раньше:
System.InvalidOperationException: The calling thread must be STA, because many UI components require this.
Я понимаю, что это значит, и после проверки, оказывается, что моя нить действительно MTA, а не STA.
Моя проблема заключается в том, что я понятия не имею, как это исправить, и где эта проблема может возникать ... Это настройка на TeamCity? MSpec? Опять же, он работал до того, как я переключился на .NET 4.
Я пробовал много разных решений, но ничего не работало.
Я также немного озадачен тем фактом, что никто не сообщал об этом раньше (с моим конкретным стеком теста TeamCity + MSpec + WPF), что может означать, что я что-то делаю неправильно.
Если у вас есть ключ, пожалуйста, дайте мне знать!
Полное исключение:
System.InvalidOperationException: The calling thread must be STA, because many UI components require this.
at System.Windows.Input.InputManager..ctor()
at System.Windows.Input.InputManager.GetCurrentInputManagerImpl()
at System.Windows.Input.KeyboardNavigation..ctor()
at System.Windows.FrameworkElement.EnsureFrameworkServices()
at System.Windows.FrameworkElement..ctor()
at System.Windows.Controls.Control..ctor()
at MyCompany.Dashboard.Client.Plugins.Common.Controls.Grids.CashflowGrid.ViewModel.ConfigureViewModel.CreateItem(String name) in d:\Program Files\JetBrains\BuildAgent2\work\6dd9af6ae2f9bbb9\Code\Src\MyCompany\Dashboard\Client\Plugins\Common\Controls\Grids\CashflowGrid\ViewModel\ConfigureViewModel.cs:line 171
at MyCompany.Dashboard.Client.Plugins.Common.Controls.Grids.CashflowGrid.ViewModel.ConfigureViewModel.Initialise(Type type, IList`1 currentSelection, Action`1 selectionChangedCallback) in d:\Program Files\JetBrains\BuildAgent2\work\6dd9af6ae2f9bbb9\Code\Src\MyCompany\Dashboard\Client\Plugins\Common\Controls\Grids\CashflowGrid\ViewModel\ConfigureViewModel.cs:line 37
at UnitTests.Plugins.Common.Controls.Grids.CashflowGrid.ViewModel.when_some_items_are_selected_on_the_chosen_list.<.ctor>b__1() in d:\Program Files\JetBrains\BuildAgent2\work\6dd9af6ae2f9bbb9\Code\Src\UnitTests.Plugins.Common\Controls\Grids\CashflowGrid\ViewModel\ConfigureViewModelTests.cs:line 82
За исключением этого, код просто пытается создать экземпляр ListBoxItem, ничего особенного, но делать это на MTA нить разбивает его.
Что я пробовал:
Установка текущего потока в ГНА
Thread.CurrentThread.SetApartmentState (ApartmentState.STA)
Это, конечно, не работает, потому что это возможно только до начала нити
Запустите код в отдельном потоке, который был инициализирован как STA: очень сложный, поскольку из-за характера MSpec разные методы вызывают в разное время, поэтому вы не можете запускать ВСЕ в одном и том же потоке. Точнее, вы не можете запустить «Установить контекст» в том же потоке, что и оператор «Из-за».
Использовать атрибут STAThread ... да, но где? никогда не работал где-нибудь я пытался
Пример неисправного теста:
public class StaTestExample
{
Establish context =() => _control = new ListBox();
It should_not_be_null =() => _control.ShouldNotBeNull();
protected static Control _control;
}
Работает ли ваш spec, когда вы просто запускаете его с помощью консольного бегуна? Если это так, ваша проблема не связана с TeamCity. BTW, программа mspec.exe.Main() присваивается '[STAThread]'. –
Это никогда не бывает проблемой при тестировании бегунов. [STAThread] не работает, он распознается только на входной точке программы. Не работает на тестовом бегуне, точка входа - это сам бегун, а не проверенный код. У большинства тестирующих участников есть возможность указать, должен ли тестовый поток быть MTA или STA, я не вижу его для mspec. –
MSpec поддерживает только STAThread. Я не совсем понимаю, что вы имеете в виду, @HansPassant. Выполняется ли спецификация с mspec.exe (консольным тестовым бегуном) или нет? –