4

我正在对在测试中执行以下操作的一段代码运行单元测试:

Assert.IsNotNull(target.Icon);

在 Icon 属性的 getter 中,我这样做:

System.Windows.Controls.Image img = new System.Windows.Controls.Image();

这引发了这个异常: System.InvalidOperationException :调用线程必须是 STA,因为许多 UI 组件都需要这个。

我理解这意味着什么,并且我知道我需要使用 Dispatcher,但我对如何或为什么有点困惑......这是我的 ViewModel 的一个属性,运行时我没有得到任何这些异常应用程序。

其他信息:这只是在我升级到 .NET 4 时才开始失败。

4

4 回答 4

1

运行单元测试的线程不是 STA 线程,您可以像这样创建一个 STA 线程:

Thread backgroundThread;
backgroundThread = new Thread(DoWork);
backgroundThread.SetApartmentState(ApartmentState.STA);
backgroundThread.Start();

我不知道您正在使用什么单元测试框架以及如何更改它的线程模型,但您需要在 Thread.Start 之前以某种方式调用 Thread.SetApartmentState 才能使其工作。

“公寓状态”是 COM 的东西,WPF 需要它,因为(如错误所说)许多 WPF 控件需要 COM,STA 线程不会自动具有与之关联的调度程序。

通常你不需要担心调度员,如果需要,系统会创建一个。

如果您确实需要为您可以读取的线程创建调度程序Dispacher.CurrentDispacher- 但您将无法对该调度程序执行任何有意义的操作,除非您让它控制线程(通过调用 Dispacher.Run)。

于 2010-06-09T06:25:50.917 回答
1

这里的问题是您正在对需要 STA 才能正常运行的 WPF 进行单元测试,但单元测试框架正在使用 MTA。您需要设置单元测试框架以在 STA 中运行测试。

每个框架都有不同的方法。通常您只需在 google 中输入测试框架名称和 STA 即可找到它。

于 2010-06-09T06:36:12.130 回答
0

您是否使用任何其他非 UI 线程?如果是这样,您确定他们不访问此属性吗?检查您是否正在使用框架中使用线程或异步运行的任何组件(如 FileSystemWatcher),这些组件可能会使用此属性。然而,更多的代码会有所帮助。

于 2010-06-09T05:22:18.407 回答
0

我认为您可能需要稍微改变您的方法。我认为您需要做的是修改您的 ViewModel,以便您公开图像的 URI,而不是 Image 控件。

在您的单元测试中,您将能够验证图像源将设置到正确的位置,并且在您的 UI 中,您只需将图像控件的源数据绑定到 URI。

于 2010-06-09T08:42:34.383 回答