【问题标题】:Progress bar is not updating on another form进度条未在其他表单上更新
【发布时间】:2018-05-22 14:16:56
【问题描述】:

我必须从特定文件夹中删除文件和子文件夹,同时删除文件进度条应该显示另一个表单上的进度条。

我已经为此采取了后台工作人员。进度条值发生异常变化,但屏幕进度条未显示更新百分比。

我正在使用visual studio 2005。因为这是旧项目。

private void EmptyFolder(DirectoryInfo directoryInfo, long totalSize, frmProgress frmProgressLbl, ref long deletedSize)
{
    short percent;
    //long deletedSize=0;
    try
    {
        foreach (FileInfo file in directoryInfo.GetFiles())
        {
            try
            {
                deletedSize += file.Length;
                file.Delete();
                percent = Convert.ToInt16((deletedSize * 100) / totalSize);
                frmProgressLbl.Percent = percent;
            }
            catch (Exception ex)
            {

            }
        }
        foreach (DirectoryInfo subfolder in directoryInfo.GetDirectories())
        {
            EmptyFolder(subfolder, totalSize,frmProgressLbl,ref deletedSize);
        }
    }
    catch (Exception ex)
    {

    }
}

下面是进度条所在表单上的代码。

public partial class frmProgress : Form
{
    private short percent;
    public short Percent { set { percent = value; } }
    private BackgroundWorker bgWorker;
    public frmProgress()
    {
        InitializeComponent();

        this.bgWorker = new BackgroundWorker();
        this.bgWorker.WorkerReportsProgress = true;
        this.bgWorker.WorkerSupportsCancellation = true;
        this.bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork);
        this.bgWorker.RunWorkerAsync();
    }

    private void frmProgress_Load(object sender, EventArgs e)
    {
        this.label1.Text = "Deleting Files...";
        this.bgWorker.RunWorkerAsync();
    }
    void bgWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        this.progressBar1.Value = percent;
    }
}

感谢您的帮助。

【问题讨论】:

  • 不要写空的 try/catch 你永远看不到你的程序为什么会失败。
  • 见:ProgressChangedEventHandler。如果您阅读了 BackgroundWorker 的 MSDN 定义,您会发现一个完整的示例代码,它与您的代码完全一样(顺便说一句,您调用了两次 RunWorkerAsync(),但是工作方法 @987654327 @, 从未被引用)。
  • 您的BackgroundWorker 在DoWork 中执行完这一行之后就完成了它的工作。您必须让 BackgroundWorker 保持活动状态。
  • 为自己省去很多痛苦——永远不要写catch (Exception ex),尤其是{ }。只有当它是特定的(即不是Exception)并且只有当你能够有意义地处理它时才能捕获它。
  • @Nandu BGW 是为了在后台工作,而不是在“后台”更新表单。您不能从另一个线程修改 UI,仅此而已。您应该将 loop 放在DoWork 中,并使用ProgressChanged 事件报告进度。

标签: c# winforms


【解决方案1】:

您可以借助以下代码实现

private void buttonDelete_Click(object sender, EventArgs e)
{
    // Start your task
    backgroundWorker.RunWorkerAsync();
}

private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {                
                #region Write logic to delete files in this region

                var totalFiles = 100;

                for (int i = 1; i <= totalFiles; i++)
                {                    
                    // Report progress
                    backgroundWorker.ReportProgress((i * totalFiles) / 100);

                    System.Threading.Thread.Sleep(200);
                } 

                #endregion                
        }

private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {                
                // Update prgores bar
                progressBar.Value = e.ProgressPercentage;                
        }  

private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {                
                // Do further process when your task is completed                
        }   

【讨论】:

  • 如果你删除了非常糟糕的try/catch (Exception ex) { throw ex; },那么我会投票。现在这段代码是制造错误的秘诀。
  • 是的,你是对的。我知道在每个方法或事件中编写 try catch 块是一种不好的做法。
  • 纯代码答案不被认为是好的答案。为什么这回答了OP的问题?这与原始代码有何不同?我不会问“为什么要使用 BGW”,也不会提到 catch{}
  • 在一个问题中,他正在更新“DoWork”事件中的进度条“this.progressBar1.Value = percent;”所以它会抛出跨线程异常,所以在“ProgressChanged”事件中更新 ui 的正确方法
  • @AdvaitBaxi 在答案本身中解释了这一点。顺便清理一下答案,绝对没有必要隐藏异常。
【解决方案2】:

我在 frmProgress 表单上编写了删除文件的方法,它解决了我的问题。

谢谢大家。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-09
    • 2013-07-12
    • 1970-01-01
    • 1970-01-01
    • 2015-08-07
    • 1970-01-01
    • 1970-01-01
    • 2011-12-17
    相关资源
    最近更新 更多