【问题标题】:Check to see if a thread in another form is still running检查其他形式的线程是否仍在运行
【发布时间】:2011-08-09 18:43:58
【问题描述】:

我有一个涉及两个窗体的 Windows 窗体应用程序。子表单用于将数据导出为 CSV 文件,并使用后台工作人员编写文件。在发生这种情况时,我隐藏了表单。 在后台工作程序运行时父表单仍然处于活动状态,因此即使后台工作程序正在写入文件,用户也可以退出应用程序。在父窗体上,我添加了一个 FormClosing 事件处理程序,以提示用户后台工作人员是否仍在运行。 我遇到的问题是访问父表单中的后台工作人员。这是我尝试过的......

    private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
    {
        ExportForm eForm = new ExportForm(GridView, TableName, GridProgressBar, ProgressLabel);

        if (eForm.PartWorker.IsBusy == true)
            MessageBox.Show("Busy");
    }

问题在于它正在创建子窗体的新实例,因此后台工作人员的 IsBusy 属性永远不会为真。我怎样才能在我的父表单中访问这个后台工作人员,以便我可以检查这个条件是否为真。

这是 PartWorker BackgroundWorker 的代码...

    #region PartWorker Events

    void PartWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        GetSwitch();
        int batchNum = 0;
        bool done = false;
        ProgressLabel.Visible = true;

        while (!done)
        {
            for (int i = 1; i <= 100; i++)
            {
                Thread.Sleep(100);
                PartWorker.ReportProgress(i);
            }

            done = Export.ExportPartition(SaveFile, DataTable, 50000, batchNum++);
        }
    }

    void PartWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        Progress.Style = ProgressBarStyle.Blocks;
        Progress.Value = e.ProgressPercentage;
        //May want to put the file name that is being written here.
        ProgressLabel.Text = "Writing File: " + e.ProgressPercentage.ToString()  +"% Complete";
    }

    void PartWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        Progress.Value = 100;
        ProgressLabel.Visible = false;
        Progress.Visible = false;
        MessageBox.Show("Files sucessfully created!", "Files Saved", MessageBoxButtons.OK, MessageBoxIcon.Information);
        PartWorker.Dispose();
        this.Close();
    }
    #endregion

【问题讨论】:

    标签: c# winforms visual-studio-2010 backgroundworker


    【解决方案1】:

    在主窗体中保存对子窗体的引用:

    class MainForm : Form {
        private ExportForm exportForm;
    
        // assign exportForm wherever the child form is created
    }
    

    接下来,在您的 ExportForm 中,创建一个属性来指示表单仍处于忙碌状态。
    这是比访问其BackgroundWorker(阅读:封装)更好的方法。

    class ExportForm : Form {
        public bool IsBusy {
            get { return this.PartWorker.IsBusy; }
        }
    }
    

    然后通过访问新创建的属性在主窗体中进行检查:

    void MainForm_FormClosing(object sender, FormClosingEventArgs e)
    {
        if (this.exportForm.IsBusy)
            MessageBox.Show("Busy");
    }
    

    【讨论】:

    • 我已经实现了这个,我可以看到它是如何工作的。但是,当我在 MainForm_FormClosing 事件中设置断点时,它会转到 ExportForm 中的 PartWorker_ProgressChanged 事件并遍历该事件处理程序。发生这种情况时,它永远不会执行 MessageBox.Show("Busy") 方法。
    • 我不太明白你在说什么。它什么时候进入ProgressChanged 处理程序?如果不设置断点会怎样?
    • 是的,它转到进度更改处理程序。如果我不设置断点,MessageBox 永远不会显示,并且您无法退出应用程序。我将发布我的 BackgroundWorker 事件处理程序的代码。我很确定问题出在那儿。
    • 顺便说一句,看看this thread
    【解决方案2】:

    创建一个包含后台工作人员或后台工作人员集合(如果您可能有多个)的单例业务对象。将您的后台工作人员从子表单创建到此单例中,应用程序域中的所有人都可以访问它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-21
      相关资源
      最近更新 更多