创建 System.Windows.Controls.Image 会引发异常 - 如何使用调度程序来实例化它?
我正在对一段代码运行单元测试,该代码在测试中执行以下操作:
Assert.IsNotNull(target.Icon);
在 Icon 属性的 getter 内部,我正在执行以下操作:
System.Windows.Controls.Image img = new System.Windows.Controls.Image();
这会引发此异常: System.InvalidOperationException :调用线程必须是 STA,因为很多 UI 组件都需要这个。
我明白这意味着什么,并且我明白我需要使用调度程序,但我对如何或为什么有点困惑......这是我的 ViewModel 的属性,并且在运行时我没有遇到任何这些异常该应用程序。
其他信息:当我升级到 .NET 4 时,这才开始失败。
I'm running my unit tests on a piece of code that does the following in the test:
Assert.IsNotNull(target.Icon);
Inside the getter for the Icon property, I'm doing this:
System.Windows.Controls.Image img = new System.Windows.Controls.Image();
That's throwing this exception: System.InvalidOperationException : The calling thread must be STA, because many UI components require this.
I understand what that means, and I understand that I need to use the Dispatcher, but I'm a bit confused about how or why... this is a property of my ViewModel and I don't get any of these exceptions when running the application.
Other info: this only started failing when I upgraded to .NET 4.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这里的问题是您正在单元测试 WPF,它需要 STA 才能正常运行,但单元测试框架正在使用 MTA。您需要设置单元测试框架才能在 STA 中运行测试。
每个框架都有不同的实现方式。通常你只需在google中输入测试框架名称和STA就可以找到它。
The problem here is that you are unit testing WPF which requires an STA to run properly but the unit testing framework is using an MTA. You need to setup your unit testing framework to run your tests in an STA.
Each framework has a different way of doing it. Usually you can find it by just typing the testing framework name and STA into google.
运行单元测试的线程不是 STA 线程,您创建一个这样的 STA 线程:
我不知道您正在使用什么单元测试框架以及如何更改它的线程模型,但您需要在 Thread 之前以某种方式调用 Thread.SetApartmentState .开始让它发挥作用。
“公寓状态”是一个 COM 事物,WPF 需要它,因为(如错误所述)许多 WPF 控件需要 COM,STA 线程不会自动具有与其关联的调度程序。
通常您不需要担心调度程序,系统会根据需要创建一个调度程序。
如果您确实需要为线程创建一个调度程序,您只需读取 Dispacher.CurrentDispacher 即可 - 但您将无法使用该调度程序做任何有意义的事情,除非您让它控制线程(通过调用调度程序.运行)。
The thread running the unit test is not an STA thread,you create an STA thread like that:
I don't know what unit testing framework you are using and how to change it's threading model but you need to somehow call Thread.SetApartmentState before Thread.Start for this to work.
The "apartment state" is a COM thing, it is required by WPF because (as the error say) many WPF controls require COM, an STA thread does not automatically have a dispatcher associated with it.
Usually you don't need to worry about the dispatcher, the system will create one if needed.
In case you do need to create a dispatcher for the thread you can just read
Dispacher.CurrentDispacher
- but you will not be able to do anything meaningful with that dispatcher unless you let it control the thread (by calling Dispacher.Run).您是否使用任何其他非 UI 线程?如果是这样,您确定他们不会访问此属性吗?检查您是否正在使用框架中使用线程或异步运行的任何组件(例如 FileSystemWatcher),这些组件可能会使用此属性。不过,更多代码会有所帮助。
Are you using any other Non-UI thread? If so, are you sure that they don't access this property? Check if you're using any components in the framework that uses thread or runs asynchronously (like FileSystemWatcher) which may use this property. However some more code would help.
我认为您可能需要稍微改变一下您的方法。我认为您需要做的是修改 ViewModel,以便公开图像的 URI,而不是图像控件。
在单元测试中,您将能够验证图像源是否设置到正确的位置,并且在 UI 中,您只需将 Image 控件的源数据绑定到 URI。
I think that you might need to change your approach a little. What I think you will need to do is modify your ViewModel so that you are exposing the URI of the image, rather than an Image control.
In your unit test you'll be able to validate that the image source will be set to the correct location, and in your UI, you'll just need to databind the source of an Image control to the URI.