[英]Exploiting the BackGroundWorker for cross-thread invocation of GUI actions on Winforms controls?
[英]Why can you cross thread adding controls in WinForms, but not WPF?
在虚拟WinForms应用程序中,我能够在设计时创建ListBox,在运行时创建后台线程,然后从后台线程向ListBox添加控件。 但如果我在WPF中做同样的事情,我会收到错误。
为什么我能在WinForms中执行此操作,但不能在WPF中执行此操作? 我的WinForm示例与WPF示例不一样吗? 或者确实有一个理由说它在WinForms中工作得很好而不是WPF?
的WinForms:
private List<Label> _labels;
public Form1()
{
InitializeComponent();
Thread test = new Thread(DoStuff);
test.SetApartmentState(ApartmentState.STA);
test.Start();
}
private void DoStuff()
{
_labels = new List<Label>();
_labels.Add(new Label() { Text = "Label1" });
_labels.Add(new Label() { Text = "Label2" });
_labels.Add(new Label() { Text = "Label3" });
if (listBox1.InvokeRequired)
{
listBox1.Invoke((MethodInvoker)delegate { listBox1.DataSource = _labels; });
}
else
{
listBox1.DataSource = _labels;
}
}
WPF:
public partial class MainWindow : Window
{
private ObservableCollection<Label> _labels;
public MainWindow()
{
InitializeComponent();
Thread test = new Thread(DoStuff);
test.SetApartmentState(ApartmentState.STA);
test.Start();
}
private void DoStuff()
{
_labels = new ObservableCollection<Label>();
_labels.Add(new Label() { Content = "Label1" });
_labels.Add(new Label() { Content = "Label2" });
_labels.Add(new Label() { Content = "Label3" });
this.Dispatcher.BeginInvoke((Action)(() =>{ icMain.ItemsSource = _labels; }));
}
}
这是我收到的错误。 非常标准和期望:
WinForms并不像检查跨线程问题那样严格。 这可能是因为WinForms实际上没有标签等控件。 相反,它们只是在操作系统级别实现的实际控件的包装。
由于这是一个实现细节,因此无法保证您的WinForms代码将来会继续使用。 (也就是说,它不是在积极开发中,所以它可能会继续工作。)
我想在WinForms中添加子项或者修改控件的属性也是不好的做法。 WPF只是有更高级的方法来控制从另一个线程访问UI,并在早期阶段向您发出警告。
相关问题 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.