使用后台工作程序-更新递归方法的进度的ProgressBar [英] Using a Background Worker - Update a ProgressBar on the progress of a Recursive Method

查看:51
本文介绍了使用后台工作程序-更新递归方法的进度的ProgressBar的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是我想交付给后台工作人员的一种方法,但是我正在根据如何创建我的方法而苦苦挣扎.尽您所能,它不会返回任何可以的内容,但是每次调用它时,它都需要一个directoryInfo对象.

Below is a method that I want to ship off into a background worker but I am struggling how to do it based on how created my method. As you can it doesn't return anything which is ok but it expects a directoryInfo object everytime it is recalled.

    private void getSizeForTargetDirectory(DirectoryInfo dtar)
    { 
        // generate a collection of objects. files comes first and then directories.

        foreach (Object item in collection )
        {
            if (item == file)
            {
               track the size of the files as you encounter.
            }
            else if (item == directory)
            {
                // found a new directory, recall the method. !!!
            }
        }
    }

这是我第一次使用后台工作者,所以我有点卡住了,由于这里提供的帮助,我尝试实现一些东西,但是当我意识到我的方法是递归的时候就卡住了.

This is my first time using a background worker so I'm a little stuck, I tried implementing something thanks to the help found here but got stuck when I realised my method was recursive.

如何在繁忙的循环中显示进度?

我实现了doWork事件处理程序方法,但是注意到,如果我有更多文件和文件夹需要在较低的子级别进行处理,则需要以某种方式重新调用该方法.

I implemented a doWork event handler method but noticed that i needed to somehow recall the method if I had more files and folders to process on lower sub levels.

我有一个简单的按钮单击事件处理程序,当当前选定的节点是目录时,该事件处理程序将调用我的"getSizeForTargetDirectory()"方法.

I have a simple button click event handler that calls my 'getSizeForTargetDirectory()' method when the current selected node is a directory.

 private void retrieveInfoButton_Click(object sender, EventArgs e)
    {
        // check to see if the path is valid
        // reset the labels and textfields.
        string fullPath = treeDrives.SelectedNode.FullPath;
        string sNodesName = treeDrives.SelectedNode.Text;

        if (directory) // Enter here if its a directory.
        {
            string parentPath = treeDrives.SelectedNode.Parent.FullPath;
            DirectoryInfo[] dirArray = populateFoldersArray(parentPath);

            for (int i = 0; i < dirArray.Length; i++)
            {
                if (dirArray[i].Name == sNodesName)
                {
                    getSizeForTargetDirectory(dirArray[i]);

                    // do work !

希望这可以解释我正在尝试做的事情以及我的工作方式.问题是,当我要运送的大部分工作都来自递归方法时,如何使用后台工作程序类的报告进度功能.

Hopefully that explains what I am trying to do and how I am doing it. Question is how can i use the report progress feature of the background worker class when the bulk of the work I am trying to ship is coming from a recursive method.

通过早期测试,我注意到我的getSize方法在进行了一些调整之后非常有效,并且非常迅速地报告了当前提供的文件夹的大小信息,但是随后我再次使用了功能强大的开发机,因此可能并非对所有用户都是如此.

Through early testing I noticed that my getSize method was incredibly efficient after a few tweaks and reported size information for the current supplied folder very quickley but then again I use quite a powerful dev machine so this may not be true for all users.

感谢您的阅读,希望有人能帮助您!

Thanks For Reading, Hope someone can help !!!

推荐答案

我认为使用DirectoryDirectoryInfo上的内置方法来使用递归获取所有目录或文件要简单得多.搜索选项:

I think it is much simpler to use the built-in methods on either Directory or DirectoryInfo to obtain all directories, or files, using the recursive search option:

public partial class Form1 : Form
{
    private Action<float> updateProgMethod;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        updateProgMethod = UpdateProgress;
    }

    private void GetDirectorySizeAsync(string path)
    {
        backgroundWorker.RunWorkerAsync(path);
    }

    private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        DirectoryInfo di = new DirectoryInfo((string)e.Argument);
        di.GetTotalSize(ProgressCallback);
    }

    // Takes callbacks from the GetTotalSize() method
    private void ProgressCallback(float p)
    {
        // Invokes update progress bar on GUI thread:
        this.BeginInvoke(updateProgMethod, new object[] { p });
    }

    // Actually updates the progress bar:
    private void UpdateProgress(float p)
    {
        progressBar.Value = (int)(p * (progressBar.Maximum - progressBar.Minimum)) + progressBar.Minimum;
    }
}

public static class IOExtensions
{
    public static long GetTotalSize(this DirectoryInfo directory, Action<float> progressCallback)
    {
        FileInfo[] files = directory.GetFiles("*.*", SearchOption.AllDirectories);
        long sum = 0;
        int countDown = 0;
        for (int i = 0; i < files.Length; i++)
        {
            sum += files[i].Length;
            countDown--;
            if (progressCallback != null && countDown <= 0)
            {
                countDown = 100;
                progressCallback((float)i / files.Length);
            }
        }
        return sum;
    }
}

不先知道文件或文件夹的数量就很难猜测进度!

It's hard to guess progress without knowing the number of files or folders first!

我对代码进行了一些改进.

I've improved the code a little.

这篇关于使用后台工作程序-更新递归方法的进度的ProgressBar的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆