繁体   English   中英

为什么你可以在WinForms中交叉线程添加控件,而不是WPF?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM