2

I am using a dispatcherTimer to update the progressBar's Value:

DispatcherTimer tim = new DispatcherTimer();
tim.Interval = TimeSpan.FromMilliseconds(100);
tim.Tick += delegate
{
    if (valuee < max)
    {
        prog.Value = valuee;
    }
    else
    {
        tim.Stop();
    }
};

And setting the progressBar's maximum value like this:

using (FileStream fs = File.Open(Filename, FileMode.Open))
{
    if (fs.Length > 10485760 && fs.Length <= 209715200)
        prog.Maximum = fs.Length / 1024;
    else if (fs.Length <= 10485760)
        prog.Maximum = fs.Length / 16;
    else if(fs.Length > 209715200)
        prog.Maximum = fs.Length / 1048576;
}

Then increasing the value after every iteration of the for loop:

var Input = File.OpenRead(path);
int Size = MainWindow.prog.Maximum;
for (long i = 0; i < Input.Length; i += Size)
{
    MainWindow.valuee++;
    PasswordEnter.valuee++;
    byte[] chunkData = new byte[chunkSize];
    int bytesRead = 0;
    while ((bytesRead = fsInput.Read(chunkData, 0, chunkSize)) > 0)
    {
        if (bytesRead != chunkSize)
        {
            for (int x = bytesRead - 1; x < chunkSize; x++)
            {
                chunkData[x] = 0;
            }
        }
        cryptoStream.Write(chunkData, 0, bytesRead);
    }
}

EDIT: This is how I am calling the AESCryptography class:

BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += (obj, l) => lo.Encrypt(Filename, password.Password, "main");
worker.RunWorkerAsync();

But for some reason the progressBar doesn't update until more than half the iterations are over! what's wrong?

Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
DividedByZero
  • 4,333
  • 2
  • 19
  • 33
  • What code is running on which thread(s)? What else happens in the `for` loop? – HABO Aug 25 '14 at 17:22
  • block #3 is on the other thread – DividedByZero Aug 25 '14 at 17:27
  • 1
    Is there a reason that you've avoided using the `ReportProgress`/`ProgressChanged` mechanism on the `BackgroundWorker` thread? It's worked well for me updating progress bars and status displays. Your looping code opens a file, then inside the `for` loop increments the progress (`valuee`). It appears that the `while` loop reads to end-of-file. The `for` loop then keeps having the `while` make sure that it is still at EOF since no new file is opened. (I'm assuming that `Input` and `fsInput` are supposed to be the same variable.) – HABO Aug 25 '14 at 19:14
  • @HABO post your comment as an answer so I can accept it! – DividedByZero Aug 25 '14 at 19:59

2 Answers2

2

A DispatcherTimer queues work on the Dispatcher thread, which is WPF UI thread.

This is what MSDN says regarding the execution of the timer:

The DispatcherTimer is reevaluated at the top of every Dispatcher loop. Timers are not guaranteed to execute exactly when the time interval occurs, but they are guaranteed to not execute before the time interval occurs. This is because DispatcherTimer operations are placed on the Dispatcher queue like other operations. When the DispatcherTimer operation executes is dependent on the other jobs in the queue and their priorities.

You're experiencing the lag in the progress timer because you are most likely running a long blocking operation which denies the messageloop of processing different requests.

You have two options:

  1. Move the long running operation to a background thread. I would prefer this approach.

  2. Try using the DispatcherTimer overload which takes a DispatcherPriority and specifying a higher priority. This approach still does not guarantee you'll experience change in performance, but it may help.

Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
1

Your looping code opens a file, then inside the for loop increments the progress (valuee). It appears that the while loop reads to end-of-file. The for loop then keeps having the while make sure that it is still at EOF since no new file is opened. (I'm assuming that Input and fsInput are supposed to be the same variable.)

The ReportProgress/ProgressChanged mechanism on the BackgroundWorker thread is a reliable way to handle the cross-thread intricacies of updating the UI from a background worker thread. You can use UserState to pass additional information, e.g. the name of the file currently being processed to display in a label.

HABO
  • 15,314
  • 5
  • 39
  • 57