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



作为我的应用程序迁移到。net 4的一部分,我正在努力使一些WPF单元测试再次与TeamCity一起工作。

在所有以某种方式使用WPF控件(例如listtitem)的测试中,我得到了一个以前没有得到的异常:

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 FilesJetBrainsBuildAgent2work6dd9af6ae2f9bbb9CodeSrcMyCompanyDashboardClientPluginsCommonControlsGridsCashflowGridViewModelConfigureViewModel.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 FilesJetBrainsBuildAgent2work6dd9af6ae2f9bbb9CodeSrcMyCompanyDashboardClientPluginsCommonControlsGridsCashflowGridViewModelConfigureViewModel.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 FilesJetBrainsBuildAgent2work6dd9af6ae2f9bbb9CodeSrcUnitTests.Plugins.CommonControlsGridsCashflowGridViewModelConfigureViewModelTests.cs:line 82

对于这个异常,代码只是试图实例化一个ListBoxItem,没有什么特别的,但是在MTA线程上这样做会破坏它。

What I tried:

  • 设置当前线程为STA

    Thread.CurrentThread.SetApartmentState (ApartmentState.STA)

这当然不工作,因为它只可能在线程启动之前

  • 在初始化为STA的单独线程中运行代码:非常复杂,因为由于MSpec的性质,不同的方法在不同的时间被调用,所以你不能在同一个线程下运行所有的东西。更准确地说,你不能在与"Because of"语句相同的线程上运行"Establish context"。

  • 使用statthread属性…是的,但是在哪里?我从未在任何地方工作过试着

失败的测试示例:

public class StaTestExample
{
    Establish context = () => _control = new ListBox();
    It should_not_be_null = () => _control.ShouldNotBeNull();
    protected static Control _control;
}

现在可以运行了

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

如果有人遇到这个问题,下面是我们所做的:

  • 禁用测试覆盖
  • 禁用MSPec任务:构建变为绿色
  • 重新启用覆盖和MSpec:它工作…

奇怪的是,确切的进程被应用在不同的构建服务器上(一个我们不再使用的旧服务器),它仍然失败。

我们想不出有什么别的变化

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

最新更新