作为我的应用程序迁移到.NET 4的一部分,我正努力让一些WPF单元测试再次与TeamCity一起工作。为什么我会在TeamCity上运行此MSpec测试时遇到无效操作异常(非STA线程?)?
在那个以某种方式使用WPF控件(例如列表项)的所有测试中,我得到一个异常之前,我并没有得到:
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的性质,在不同的时间调用不同的方法,所以不能在同一线程下运行EVERYTHING。更确切地说,你不能在“因为”语句的同一个线程上运行“建立上下文”。
使用STAThread属性...是的,但在哪里?从来没有在任何地方工作,我 试图
失败测试
例子:
public class StaTestExample
{
Establish context =() => _control = new ListBox();
It should_not_be_null =() => _control.ShouldNotBeNull();
protected static Control _control;
}
当你用控制台运行器运行它时,你的规格是否运行?如果是这样,你的问题与TeamCity无关。顺便说一句,mspec.exe的Program.Main()被赋予了'[STAThread]'。 – 2013-03-12 16:01:19
这对于单元测试运动员来说绝对不是问题。 [STAThread]不起作用,只能在程序的入口点处识别。对测试运行者不起作用,入口点是跑步者本身,而不是测试代码。大多数测试运行者可以选择指定测试线程是否应该是MTA或STA,我没有看到一个用于mspec。 – 2013-03-12 16:50:54
MSpec截止目前仅支持STAThread。我真的不明白你的意思,@HansPassant。该规格是否与mspec.exe(控制台测试运行器)一起运行? – 2013-03-12 16:56:04