如何使用backgroundworker打开表单?

时间:2015-07-01 11:48:50

标签: c# multithreading winforms backgroundworker

我有一个mdi表单,其中包含一些子表单。其中一种形式需要时间来加载。我需要使用backgroundworker来加载这个表单。我试过这段代码,但是我遇到了跨线程错误。实际上,我无法为我的表格设置mdiParent#39;通过backgroundworker。 任何帮助将不胜感激。

代码:

private void tsmiNewExpense_Click(object sender, EventArgs e)
    {
        tss_lbl1.Text = "Loading...";
        if (!BW1.IsBusy)
        {
            BW1.RunWorkerAsync();
        }

    }

private void BW1_DoWork(object sender, DoWorkEventArgs e)
    {
        frmNewExpense frm = new frmNewExpense();
        showChildForm(frm);
    }

    /// <summary>
    /// Checks for one instance of this form is running 
    /// </summary>
    /// <param name="frm">the form that will be shown.</param>
private void showChildForm(Form frm)
    {
        bool exists = false;
        foreach (Form item in this.MdiChildren)
        {
            if (item.Name == frm.Name)
            {
                item.Activate();
                item.StartPosition = FormStartPosition.CenterParent;
                item.WindowState = formWindowState;
                exists = true;
                break;
            }
        }
        if (!exists)
        {
            frm.MdiParent = this;//this line gets cross-thread error
            frm.StartPosition = FormStartPosition.CenterParent;
            frm.WindowState = formWindowState;
            frm.Show();
        }
    }

1 个答案:

答案 0 :(得分:0)

这是使用同步上下文来更新Form的lblTimer标签:

CS:

public partial class MainForm : Form
{
    private readonly SynchronizationContext _context;

    public MainForm()
    {
        InitializeComponent();
        // the context of MainForm, main UI thread
        // 1 Application has 1 main UI thread
        _context = SynchronizationContext.Current;
    }

    private void BtnRunAnotherThreadClick(object sender, EventArgs e)
    {
        Task.Run(() =>
                 {
                     while (true)
                     {
                         Thread.Sleep(1000);
                         //lblTimer.Text = DateTime.Now.ToLongTimeString(); // no work
                         UpdateTimerInMainThread(); // work
                     }
                 });
    }

    private void UpdateTimerInMainThread()
    {
        //SynchronizationContext.Current, here, is context of running thread (Task)
        _context.Post(SetTimer, DateTime.Now.ToLongTimeString());
    }

    public void SetTimer(object content)
    {
        lblTimer.Text = (string)content;
    }
}

enter image description here

希望得到这个帮助。