【问题标题】:BackgroundWorker & Progressbar Issues c# Visual Studio 2010c# Visual Studio 2010 BackgroundWorker 和进度条问题
【发布时间】:2012-12-10 13:48:24
【问题描述】:

我试图了解背景工作者和进度条,到目前为止,我已经让它工作了,但不完全是我想要的工作方式。基本上我正在对文件夹进行排序/重命名并将它们复制到不同的位置,这有效并且代码是不言自明的,生成的输出文件夹与预期的一样。但是,对于我打算搜索的每个文件夹,我必须右键单击它以获取文件数,然后在代码中我必须将 progressBar1.Maximum 设置为该值,以便它显示进度条的 coreect 进度.怎么可能让它自动设置文件数量,因为它无论如何都要经过每个文件夹?一些文件夹有数千个文件,而另一些文件夹有数百万个文件。除此之外,我想添加一个标签,以便它显示正在处理的文件的名称以及进度条更新。

namespace Data_Sorter
{
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void btnSelect_Click(object sender, EventArgs e)
    {
        folderBrowserDialog1.ShowDialog();
        tbFilePath.Text = folderBrowserDialog1.SelectedPath.ToString();
    }

    private void btnSort_Click(object sender, EventArgs e)
    {
        backgroundWorker1.RunWorkerAsync();
    }

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        int totalFiles = 0;
        foreach (var file in Directory.GetFiles(tbFilePath.Text, "*.txt", SearchOption.AllDirectories))
        {
            backgroundWorker1.ReportProgress(totalFiles);

            string fullFilename = file.ToString();

            string[] pathParts = fullFilename.Split('\\');
            string date = pathParts[6];

            string fileName = pathParts[7];

            string[] partName = fileName.Split('_');

            string point = partName[3];

            Directory.CreateDirectory("Data Sorted Logs\\" + point + "\\" + date + "\\");

            if (Directory.Exists(("Data Sorted Logs\\" + point + "\\" + date + "\\")))
                {
                    string destPath = (point + "\\" + date + "\\");
                    File.Copy(fullFilename, "C:\\Documents and Settings\\PC\\Desktop\\Sorter\\Data Sorter\\bin\\Debug\\Data Sorted Logs\\" + destPath + fileName);                    }
            else
                {
                    MessageBox.Show("destination folder not found " + date + point);
                }

            totalFiles++;
        }
    }

    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        MessageBox.Show("Done");
    }

    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        progressBar1.Maximum = 6777; // set this value at the maximum number of files you want to sort //
        progressBar1.Value = e.ProgressPercentage;
    }
}

【问题讨论】:

    标签: c# visual-studio-2010 loops progress-bar backgroundworker


    【解决方案1】:

    您可以通过读取 GetFiles 长度找出文件编号。

    您可以使用表达式传递相对百分比:(i * 100) / totalFiles,这样就不需要为进度设置最大值。

    您还可以将文件名报告给进度条,将其作为 UserState 在 progressChanged 事件中传递。

    试试下面的代码:

       namespace Data_Sorter
        {
        public partial class Form1 : Form
        {
    
    
    public Form1()
        {
            InitializeComponent();
        }
    
        private void btnSelect_Click(object sender, EventArgs e)
        {
            folderBrowserDialog1.ShowDialog();
            tbFilePath.Text = folderBrowserDialog1.SelectedPath.ToString();
        }
    
        private void btnSort_Click(object sender, EventArgs e)
        {
            backgroundWorker1.RunWorkerAsync();
        }
    
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            int totalFiles = 0;
            string[] files = Directory.GetFiles(tbFilePath.Text, "*.txt", SearchOption.AllDirectories);
            totalFiles = files.Length;
            int i = 0;
            foreach (var file in files)
            {
    
                backgroundWorker1.ReportProgress((i * 100) / totalFiles, file);
                i++
                string fullFilename = file.ToString();
    
                string[] pathParts = fullFilename.Split('\\');
                string date = pathParts[6];
    
                string fileName = pathParts[7];
    
                string[] partName = fileName.Split('_');
    
                string point = partName[3];
    
                Directory.CreateDirectory("Data Sorted Logs\\" + point + "\\" + date + "\\");
    
                if (Directory.Exists(("Data Sorted Logs\\" + point + "\\" + date + "\\")))
                    {
                        string destPath = (point + "\\" + date + "\\");
                        File.Copy(fullFilename, "C:\\Documents and Settings\\PC\\Desktop\\Sorter\\Data Sorter\\bin\\Debug\\Data Sorted Logs\\" + destPath + fileName);                    }
                else
                    {
                        MessageBox.Show("destination folder not found " + date + point);
                    }
    
                totalFiles++;
            }
        }
    
        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            MessageBox.Show("Done");
        }
    
        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar1.Value = e.ProgressPercentage;
            progressBar1.Text = e.UserState.ToString();//or yourNewLabel.Text = e.UserState.ToString();
        }
    }
    

    【讨论】:

    • 这很好用,我只需要将公式表达式更改为 i*200 / totalFiles 因为进度条会在操作完成时正好停在中途点。我学到了很多谢谢......
    • 太好了,很高兴为您提供帮助!我看到循环的最后一条指令是totalFiles++,你必须删除它,因为它不是必需的,并且会破坏公式的含义((i * 100)/totalFiles)。这就是为什么您必须将 100 更改为 200。希望很清楚。
    【解决方案2】:

    上移对 GetFiles 的调用,以便获得它返回的数组的长度:

    string[] files = Directory.GetFiles(tbFilePath.Text, "*.txt",
                                        SearchOption.AllDirectories));
    
    // Note - you won't be able to set this UI property from DoWork 
    // because of cross-thread issues:
    // progressbar1.Maximum = files.Length; 
    
    int fileCount = files.Length;   
    
    foreach (var file in files ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-07
      • 1970-01-01
      • 2011-08-09
      • 2012-05-27
      相关资源
      最近更新 更多