2013-03-12 4 views
2

Как часть переноса моего приложения на .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; 
} 
+0

Работает ли ваш spec, когда вы просто запускаете его с помощью консольного бегуна? Если это так, ваша проблема не связана с TeamCity. BTW, программа mspec.exe.Main() присваивается '[STAThread]'. –

+0

Это никогда не бывает проблемой при тестировании бегунов. [STAThread] не работает, он распознается только на входной точке программы. Не работает на тестовом бегуне, точка входа - это сам бегун, а не проверенный код. У большинства тестирующих участников есть возможность указать, должен ли тестовый поток быть MTA или STA, я не вижу его для mspec. –

+0

MSpec поддерживает только STAThread. Я не совсем понимаю, что вы имеете в виду, @HansPassant. Выполняется ли спецификация с mspec.exe (консольным тестовым бегуном) или нет? –

ответ

0

Он теперь работает.

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

В случае, если кто получает эту проблему, вот что мы сделали:

  • Отключение тестового покрытия
  • Отключение задачи MSPec: сборка идет зеленый
  • Повторное включение освещения и MSpec: она работает. ..

Странно, что точный процесс был применен на другом сервере сборки (старый, который мы больше не используем), и он все еще терпит неудачу.

Нет ничего другого, что мы могли бы подумать об этом.

Так что это немного загадка ... Надеюсь, он не вернется, чтобы укусить нас!

+0

Если бы я был в вашей ситуации, мне было бы интересно, нужно ли мне действительно тестировать то, что есть в потоке. Невозможно ли разбить код, чтобы вы могли его протестировать без необходимости одновременного использования нескольких потоков? –

+0

Ну, это полностью не под моим контролем, тесты тестировали элементы управления пользовательским интерфейсом, а потоки создавались с помощью фреймворка. Он все еще отлично работает, но до сих пор не знаю, что пошло не так. Я обвиню тот факт, что я не пожертвовал козлом достаточно скоро. –