0

First of all, My code is written in Windows Form Application - C#.

I need to execute a method (which is very modular and it's runtime is depends on how much physical memory you have used in your system), and while this method is running, I want to present to the user a progressbar. I don't know how to sync the progressbar, with the function's runtime.

EDIT: HERE IS MY CODE:

public SystemProp()
    {
        // Getting information about the volumes in the system.
        this.volumes = getVolumes();

        for (int i = 0; i <volumes.Length; i++)
        {
            // Create a txt file for each volume.
            if (!System.IO.File.Exists(dirPath + volumes[i].Name.Remove(1) + @".txt"))
            {
                using (FileStream fs = File.Create(dirPath + volumes[i].Name.Remove(1) + @".txt"))
                {

                }
            }

            // Treescan function for each Volume.
            TreeScan(volumes[i].Name);
        }
    }

    private bool isSafe()
    { return true; }

    private DriveInfo[] getVolumes()
    {
        DriveInfo[] drives = DriveInfo.GetDrives();
        return drives;
    }

    private void TreeScan(string sDir)
    {
       try
       {
            foreach (string f in Directory.GetFiles(sDir))
            {
                using (FileStream aFile = new FileStream(dirPath + sDir.Remove(1) + @".txt", FileMode.Append, FileAccess.Write))
                using (StreamWriter sw = new StreamWriter(aFile)) { sw.WriteLine(f); }
            }

            foreach (string d in Directory.GetDirectories(sDir))
            {
                TreeScan(d);
            }
       }
       catch (Exception)
       { }

    }

The function is the treescan.

I would appriciate any kind of help, Thank You Very Much!!

ItayGamil
  • 1
  • 3
  • 1
    You should calculate progress and set `ProgressBar.Value` inside the method. – Valentin Feb 23 '16 at 20:40
  • What kind of application is it? Forms? WPF? – adamdc78 Feb 23 '16 at 20:41
  • @Valentin How can I calculate the progress if it depends on the physical memory you have benn used in your computer + the function's runtime? (those are dynamic) – ItayGamil Feb 23 '16 at 20:43
  • @ItayGamil What do you mean by the function's runtime? – Valentin Feb 23 '16 at 20:45
  • @ItayGamil Post your code!!! – Sorceri Feb 23 '16 at 20:46
  • @ItayGamil Is it average function duration? – Valentin Feb 23 '16 at 20:47
  • @Valentin For example, if I used 100GB in my system - the function's runtime may be 1 minute. But, if I used 20GB in my system - the function's runtime may be 20 seconds (those times aren't accurate.. I wrote them just for you to understand the concept of my question) – ItayGamil Feb 23 '16 at 20:47
  • From the sound of it you have a single task that executes (lets say, moving a file) and you want to live update while it runs... The only way I can think of doing this accurately would be to have a sub-process/thread doing the task and the other updating the bar based on some sort of algorithm for completion time. Something like: start time - now compared to expected end time. – Steve Byrne Feb 23 '16 at 20:47
  • @StevenByrne something like: If 100Gb takes 60 sec, then 1GB take 0.6 sec? Then calculate the system's size before running the function and set the interval to System Size * Time per 1GB? – ItayGamil Feb 23 '16 at 20:55
  • Something like that. Let me clarify your goal... You want to get all of the directories, sub-directories, and files in a folder. Because this takes time you want a progress bar that accurately shows how long they will have to wait until everything is found. correct? – Steve Byrne Feb 23 '16 at 21:01
  • I don't think you'll be able to show an accurate progress bar because the running time depends on the depth of your file system, which is an unknown quantity. You should provide user feedback, though; I would recommend displaying a live count of the number of folders that have been scanned so far. You'll need to move the scanning code to a background thread and periodically use BeginInvoke to update the counter on the UI thread. – RogerN Feb 23 '16 at 21:29
  • @StevenByrne Correct! – ItayGamil Feb 24 '16 at 05:10
  • @RogerN Right now Im using a thread for the progressbar (Which is in another form). If needed, I will change it.. – ItayGamil Feb 24 '16 at 05:11
  • So the hard part here is we need to know where we end before we get there. Check out these two posts and see if they give you any ideas... I'll try to think of a good way to do this and post back (please update if either of these other posts help/change anything) http://stackoverflow.com/questions/5601440/using-progressbar-while-populating-a-huge-treeview http://stackoverflow.com/questions/6044629/file-copy-with-progress-bar – Steve Byrne Feb 24 '16 at 05:21

1 Answers1

0

You should calculate progress and set ProgressBar.Value inside the method.

For example you have a for loop from 1 to 100.

for (int i = 0; i < 100; i ++) 
{
 //...
 progressBar.Value = i;
}

You can also set a maximum value of progress using Maximum property. So for a for loop from 1 to 10 you can set Maximum to 10 and don't calculate a progress.

progressBar.Maximum = 10;
for (int i = 0; i < 10; i ++) 
{
 //...
 progressBar.Value = i;
}

If you can't split you method in different stages where you can change progress value, you can create a timer that ticks every one second and change the progress value in Tick event handler. In order to set progress value based on runtime you can use Stopwatch. Timer and Stopwatch should be started in the beginning of the method.

    Timer timer = new Timer();
    Stopwatch stopwatch = new Stopwatch();

    void Method()
    {
        timer.Start();
        stopwatch.Start();
        //...
    }

    private void Timer_Tick(object sender, EventArgs e)
    {
        var progress = CalculateProgress (); // calculate progress  
        progressBar.Value = progress; 
        // or
        progressBar.Value =  stopwatch.Elapsed.Seconds;
    }
Valentin
  • 5,380
  • 2
  • 24
  • 38