如何在后台线程中创建WPF控件?我有创建后台线程来执行某些操作的方法。在这个后台线程中,我创建了对象。但是这个对象在运行时创建时给我一个异常:调用线程必须是STA,因为许多UI组件都需要这个。我知道我必须使用Dispatcher来反映UI的内容。但在这种情况下,我只是创建一个对象,而不是使用UI进行迭代。这是我的代码:publicvoidSomeMethod(){BackgroundWorkerworker=newBackgroundWorker();worker.DoWork+=newDoWorkEventHandler(Background_Method);worker.RunWorkerAsync();}voidBackground_Method(objectsender,DoWorkEventArgse){TreeViewtv=newTreeView();}如何在后台线程中创建对象?我使用WPF应用程序TreeView是一个UI控件。您只能在UI线程上创建和操作UI控件,因此您无需尝试执行任何操作。你想要做的是在后台线程上完成所有耗时的工作,然后“回调”到UI线程来操作UI。这实际上非常简单:voidBackground_Method(objectsender,DoWorkEventArgse){//...耗时的东西...//回调窗口进行UI操作this.BeginInvoke(newMethodInvoker(delegate{TreeViewtv=newTreeView();//等等,操纵}));我可能在BeginInvoke处遇到了错误的语法(这是我的想法),但无论如何你去......HTH:voidBackground_Method(objectsender,DoWorkEventArgse){//不使用UI元素的耗时操作//结果耗时操作varresult=newobject();App.Current.Dispatcher.Invoke(newAction((res)=>{//使用UITreeViewtv=newTreeView();}),result);没有人详细讨论单独STA线程的情况(即使概念完全相同)。因此,让我们假设在单击按钮时添加了一个简单的选项卡控件privatevoidbutton_Click(objectsender,RoutedEventArgse){TabItemnewTab=newTabItem(){Header="NewTab"};tabMain.Items.Add(newTab);}如果我们将它移动到另一个STA线程privatevoidbutton_Click(objectsender,RoutedEventArgse){ThreadnewThread=newThread(newThreadStart(ThreadStartingPoint));newThread.SetApartmentState(ApartmentState.STA);新线程。是背景=真;新线程.开始();}privatevoidThreadStartingPoint(){TabItemnewTab=newTabItem(){Header="NewTab"};tabMain.Items.Add(newTab);}当然我们得到一个System.InvalidOperationException现在,如果我们添加控件会发生什么tabMain.Items.Add(newTab);}使用委托方法?publicvoidDelegateMethod(stringheader){tabMain.Dispatcher.BeginInvoke(newAction(()=>{this.AddToParent(header);}),null);如果您调用privatevoidbutton_Click(objectsender,RoutedEventArgse){线程newThread=newThread(newThreadStart(ThreadStartingPoint));newThread.SetApartmentState(ApartmentState.STA);newThread.IsBackground=true;新线程.开始();}privatevoidThreadStartingPoint(){DelegateMethod("newtab");因为现在我们将可视化树保留在同一个原始线程中为了使代码正常工作,必须通过调用Thread.SetApartmentState(ApartmentState.STA)加入STACOM单元。由于BackgroundWorker可能正在使用一些共享线程池,加入一个特定的单元可能会影响这个线程池的其他用户,或者如果它之前被设置为例如,甚至可能会失败。一个MTA。即使一切顺利,你新创建的TreeView也会被锁定到这个工作线程。您将无法从主UI线程使用它。如果您更详细地解释您的真实意图,您一定会得到更好的帮助。试试这个代码:publicvoidSomeMethod(){System.ComponentModel.BackgroundWorkermyWorker=newSystem.ComponentModel.BackgroundWorker();myWorker.DoWork+=myWorker_DoWork;myWorker.RunWorkerAsync();}privatevoidmyWorker_DoWork(objectsender,System.ComponentModel.DoWorkEventArgse){//在这里做一些耗时的工作}voidBackground_Method(objectsender,DoWorkEventArgse){TreeViewtv=newTreeView();//在这里生成你的TreeView方法。我在后台线程中获取数据,然后当线程完成使用此数据时。感谢大家提供有用的方法。特别感谢Veer对e.Result属性的建议。请参阅此问题的答案:Howdo我在STA线程里跑东西?定义线程的时候把ApartmentState设置成STA:thread.SetApartmentState(ApartmentState.STA);这样应该就可以了!以上是C#学习教程:HowtocreateaWPFcontrolinthebackgroundthread?分享的所有内容,如果对大家有用,还需要了解更多C#学习教程,希望大家多多关照~本文收集自网络,不代表立场,如涉及侵权,敬请谅解点击右侧联系管理员删除。如有转载请注明出处:
