I have a windows form program. In the main form I have a label where I update with progress. I use the following code to perform my operations:
Thread workThread = new Thread(delegate ()
{
for (int i = 1; i < bytes.Length; i )
{
SliderOverBytesAndDoProcessing();
}
});
workThread.Start();
The function SliderOverBytesAndDoProcessing()
performs operations where I read 4 bytes and perform some operations on more bytes. I do this for each 4 bytes of the 200MB file (read 4 bytes process something and continue moving). Everything works fine until I decide to report my progress. Here is how I do the update:
Thread workThread = new Thread(delegate ()
{
for (int i = 1; i < bytes.Length; i )
{
Lbl.Invoke((Action)delegate { Lbl.Text = "Processing " (ii / 1048576) "/" (bytes.Length / 1048576); }
SliderOverBytesAndDoProcessing();
}
});
workThread.Start();
If I add that one line the program becomes too slow. I mean the program runs in around a few minutes without that line but with that line it takes around 1.5 hours. Also, on some other operations if I do that, I end up in infinite loops. How do I report my progress from the other thread to form thread without facing this problem.
Thanks.
CodePudding user response:
It is slow because you’re dispatching to the UI thread on every byte, even though the progress message only seems to care about megabytes. So you change the label over a million times to the same value.
Consider
var totalMb = bytes.Length / 1024 / 1024;
var lastMb = -1;
for (int i = 1; i < bytes.Length; i ) {
var currentMb = i / 1024 / 1924;
if (currentMb > lastMb) {
Lbl.Invoke(() => { Lbl.Text = $"Processing {currentMb}/{totalMb} MiB" });
lastMb = currentMb;
}
SliderOverBytesAndDoProcessing();
}