Reputation: 4391
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?
Upvotes: 2
Views: 966
Reputation: 15816
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.
Upvotes: 1
Reputation: 149538
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:
Move the long running operation to a background thread. I would prefer this approach.
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.
Upvotes: 2