从 BackgroundWorker 创建控件

Create control from BackgroundWorker

我有这个代码:

    public Form1()
    {
        InitializeComponent();

        BackgroundWorker bw = new BackgroundWorker();
        bw.WorkerSupportsCancellation = true;
        bw.WorkerReportsProgress = true;
        bw.DoWork += (s, ev) => show();
        bw.RunWorkerAsync();
    }

    private void show()
    {
        MessageBox.Show("aaaaaa");

        PictureBox load = new PictureBox();
        load.BackColor = Color.White;
        load.Width = this.Width;
        load.Height = this.Height;
        load.Left = 0;
        load.Top = 0;
        load.Name = "load";

        this.Controls.Add(load);
        load.BringToFront();

        MessageBox.Show("bbbbb");
    }

PictureBox 将不会创建,"bbbbb" MessageBox 不会出现。

问题是什么?

问题是,您在运行 GUI 的 Thread 中创建控件。BackgroundWorker 有一个事件 RunworkerCompletedDoWork 之后触发事件处理程序完成。 RunworkerCompleted 然后在调用 DoWorkThread 中运行(在您的例子中是主线程)。所以你在 DoWork 中完成所有非 GUI 相关的工作,在 RunWorkerCompleted:

中完成 GUI 相关的工作
public Form1()
{
    InitializeComponent();

    BackgroundWorker bw = new BackgroundWorker();
    bw.WorkerSupportsCancellation = true;
    bw.WorkerReportsProgress = true;
    bw.DoWork += (s, ev) => calculate();
    bw.RunWorkerCompleted += (s, ev) => show();
    bw.RunWorkerAsync();
}

private void calculate()
{
     // Do some heavy work
     Thread.Sleep(5000);
}

private void show()
{
    MessageBox.Show("aaaaaa");

    PictureBox load = new PictureBox();
    load.BackColor = Color.White;
    load.Width = this.Width;
    load.Height = this.Height;
    load.Left = 0;
    load.Top = 0;
    load.Name = "load";

    this.Controls.Add(load);
    load.BringToFront();

    MessageBox.Show("bbbbb");
}