我在一段代码中运行我的单元测试,该代码在测试中执行以下操作:
Assert.IsNotNull(target.Icon);
在Icon属性的getter中,我这样做:
System.Windows.Controls.Image img = new System.Windows.Controls.Image();
抛出此异常:System.InvalidOperationException:调用线程必须是STA,因为许多UI组件都需要这个。
我理解这意味着什么,我明白我需要使用Dispatcher,但我对如何或为什么有点困惑...这是我的ViewModel的一个属性,我没有得到任何这些运行应用程序时的异常。
其他信息:这只在我升级到.NET 4时才开始失败。
答案 0 :(得分: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),否则您将无法对该调度程序执行任何有意义的操作。运行)。
答案 1 :(得分:1)
这里的问题是你是单元测试WPF,它需要STA正常运行,但单元测试框架正在使用MTA。您需要设置单元测试框架以在STA中运行测试。
每个框架都有不同的方式。通常只需在google中键入测试框架名称和STA即可找到它。
答案 2 :(得分:0)
您使用的是其他任何非UI线程吗?如果是这样,您确定他们不访问此属性吗?检查您是否在框架中使用任何使用线程的组件或异步运行(如FileSystemWatcher),这些组件可能使用此属性。然而,一些更多的代码会有所帮助。
答案 3 :(得分:0)
我认为你可能需要改变一下你的方法。我认为您需要做的是修改您的ViewModel,以便您公开图像的URI,而不是图像控件。
在单元测试中,您将能够验证图像源是否将设置到正确的位置,并且在UI中,您只需要将Image控件的源数据绑定到URI。