2

我正在尝试使用以下代码使用后台工作线程在单独的线程中在单独的线程中显示另一个表单而不是主表单:

    private void simpleButton1_Click(object sender, EventArgs e)
    {
        //this.Opacity = 50.5;
        bw.RunWorkerAsync();                      
        GetData();
        bw.CancelAsync();

    }

    private void GetData()
    {
        for (int i = 0; i < 500000; i++)
        {
            datatable.Rows.Add(new object[] { "raj", "raj", "raj", i });
        }
    }

    void bw_DoWork(object sender,DoWorkEventArgs e)
    {

        XtraForm1 frm = new XtraForm1();
        while (!bw.CancellationPending)
        {
            frm.ShowDialog();
            frm.BringToFront();
            continue;
        }
        e.Cancel = true;
    }

但问题是,当我单击主窗体时,在单独线程中运行的另一个窗体会隐藏。在主线程完成执行之前如何使其可见,然后很好地处理它?

4

2 回答 2

3

简单的答案是:你没有。UI 有一个线程来完成所有可见的用户交互,在将控制权交给工作人员之前,应该是 UI 的工作来向您的用户显示一个漂亮的“正在工作...”窗口。工作人员完成后,可以关闭窗口。

您的“主”(UI)线程永远不应该“忙”。那会冻结你的窗口。将所有工作加载到您的后台任务中,并让主线程闲置等待您的工作人员完成。您的工作线程可能会一直忙于无休止的循环,您的 UI 仍然会响应。即使响应只是“仍在工作,对不起”。

于 2013-10-04T05:43:33.527 回答
2

你应该反过来做。将您的循环移动到BackgroundWorker主线程中的并保留 UI 内容(显示您的辅助表单)。然后使用BackgroundWorker'sReportProgressRunWorkerCompleted来正确显示/隐藏您的辅助表单。

它看起来像这样: XtraForm1 frm = new XtraForm1();

private void simpleButton1_Click(object sender, EventArgs e)
{
    bw.ReportsProgress = true;
    bw.RunWorkerAsync();                      
    frm.ShowDialog();
}

private void GetData()
{
    for (int i = 0; i < 500000; i++)
    {
        datatable.Rows.Add(new object[] { "raj", "raj", "raj", i });
        if(i%1000==0) bw.ReportProgress((int)((i/500000f)*100));
    }
}

void bw_DoWork(object sender,DoWorkEventArgs e)
{
    GetData();
}

void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    //update your secondary form's UI here. I'm supposing you have a ProgressBar
    //on your form named 'pbr' (make that control public)
    frm.pbr.Value = e.ProgressPercentage;
}    

void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    frm.Hide();
}    
于 2013-10-04T05:42:13.190 回答