为什么我在TeamCity上运行此MSpec测试会得到无效操作异常(非STA线程?)?

时间:2013-03-12 14:43:08

标签: .net-4.0 teamcity mspec sta

作为将我的应用程序迁移到.NET 4的一部分,我很难让一些WPF单元测试再次与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线程上这样做就会破坏它。

我尝试了什么:

  • 将当前线程设置为STA

    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;
}

1 个答案:

答案 0 :(得分:0)

它现在有效。

但问题是我们无法解释它。它仍然在不同的构建服务器上失败,但我们并不关心这个。

如果有人遇到这个问题,我们在这里做了什么:

  • 禁用测试覆盖率
  • 禁用MSPec任务:构建变为绿色
  • 重新启用覆盖范围和MSpec:它有效......

奇怪的是,确切的过程应用于不同的构建服务器(我们不再使用的旧服务器),它仍然失败。

我们没有别的想法会改变。

所以这有点神秘......我希望它不会再回来咬我们了!