在后台线程WPF中创建UI?
我试过以下:
var task = new Task(() => { for (int i=0; i { label.Content = printerStatus(); // will return "Out of Paper", "printing", "Paper jam", etc. }, TaskScheduler.FromCurrentSynchronizationContext()); label.Content = "Sending to printer";
它返回以下错误:调用线程必须是STA,因为许多UI组件需要这个..
尝试创建新的UI对象Grid时发生错误。
我怎样才能解决这个问题? 如果还有其他任何方式让我知道!
任务使用MTA中的线程池线程。
如果您需要后台STA线程,则必须自己创建一个并明确设置ApartmentState
。
Thread t = new Thread( ... ); t.SetApartmentState( ApartmentState.STA ); t.Start();
使用Dispatcher作为标签和Invoke可能会有所帮助:
label.Dispatcher.Invoke( System.Windows.Threading.DispatcherPriority.Normal, new Action( delegate() { label.Content = printerStatus(); } ));
您不能在与主UI线程不同的线程上创建UI对象,因为只要将它们添加到UI,它就会尝试设置Parent
属性,并且WPF中的线程无法修改在不同线程上创建的对象。
相反,我建议在第二个线程上创建Grid的数据列表或集合,并使用类似ItemsControl
东西将其绑定到UI。 这将使所有UI对象保持在主UI线程上,而后台处理可以在后台线程上完成。
要从后台线程(例如状态标签)更新UI对象,我建议使用Dispatcher
如lawrencealan的回答所示。 Dispatcher
是WPF的主UI线程的内部消息队列