【问题标题】:Show another form over main form in separate thread在单独的线程中显示另一个表单而不是主表单
【发布时间】:2013-10-04 05:37:04
【问题描述】:

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

    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;
    }

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

【问题讨论】:

  • 为什么要在线程而不是 UI 线程中创建 UI 元素?
  • 使用模态对话框.. 不是这个.. :/
  • 我想在主线程忙于执行时显示诸如启动画面之类的显示等待..文本
  • @SimonWhitehead 我如何在这里使用模态对话框..
  • @SimonWhitehead 你的意思是说我需要在主线程中运行启动屏幕表单并在辅助线程中进行其他处理?

标签: c# multithreading


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    它看起来像这样: 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();
    }    
    

    【讨论】:

    • 我不能这样做,因为我在主线程中没有任何操作。所以不能在后台工作线程中做所有事情
    • @RajeevKumar 你可以。您的后台线程可以在忙于工作时向 UI 线程报告进度。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-05
    • 1970-01-01
    • 1970-01-01
    • 2013-02-13
    相关资源
    最近更新 更多