Iam尝试在Workflow Com服务中创建WPF窗口 但我得到以下错误:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> 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.InputManager.get_Current()
at System.Windows.Input.KeyboardNavigation..ctor()
at System.Windows.FrameworkElement.FrameworkServices..ctor()
at System.Windows.FrameworkElement.EnsureFrameworkServices()
at System.Windows.FrameworkElement..ctor()
at System.Windows.Controls.Control..ctor()
at System.Windows.Window..ctor()
at PACIExpress.SelectLanguage..ctor()
有人能帮帮我吗?
答案 0 :(得分:2)
Exception确切地说明了问题:
System.InvalidOperationException:调用线程必须是STA,因为许多UI组件都需要这个。
首先,如果'Workflow Com Service'类似于WCF或Web服务,那么它不是可以拥有用户界面的桌面应用程序。
您的应用必须是STA。
MTA和STA之间的区别:
有关WPF和STA的信息: http://msdn.microsoft.com/en-gb/magazine/cc163328.aspx
如果你有一个入口点方法,你想使用STAThread属性,请参阅此处获取更多信息:
http://blogs.msdn.com/b/jfoscoding/archive/2005/04/07/406341.aspx http://msdn.microsoft.com/en-us/library/system.stathreadattribute.aspx
希望有所帮助!
答案 1 :(得分:2)
Kieren的回答解释了问题的本质,即Workflow Foundation线程是MTA线程,而WPF需要STA线程。 Kieren的回答并未解释如何解决问题。
每当我需要从MTA线程访问WPF内容时,我都会创建一个用于访问内容的STA线程。我已经使用了两个解决方案,这两个解决方案都运行良好:
合并的STA线程
当WPF对象不需要存在于当前方法调用之外时,我使用我编写的STAThreadPool类。 STAThreadPool实现System.Threading.ThreadPool的基本功能,但创建其线程STA而不是MTA。它还有一个RunOnSTAThread方法,该方法对用户工作项进行排队,然后等待该项完成。
专用STA线程
此解决方案具有更多开销,但是在任何时候WPF对象可能存在多个方法调用时都需要。同样有一个“RunOnSTAThread”方法,在这种情况下通过以下方式实现:
每个STA线程运行一个执行此操作的循环:
这个解决方案实际上比编写良好的STAThreadPool更少的代码,但如果有很多线程可能效率较低。