Trying to do progress bar - hangs on method invocation

T

trant

I have a Form with a progress bar and a thread that should update the
progress every quarter of a second. The operation being monitored for
progress on is a file loading job.

So I start off the monitor like this:

long currprogress = 0;
FileInfo info = new FileInfo(currFile);
long maxprogress = info.Length / 100;
bool IsMonitoring = true;
Thread monitor = new Thread(new ThreadStart(RunMonitor));
monitor.Start();

(the scope of these variables is class level though, just made them local
scope for easier reading)

Then my RunMonitor method looks like:

private void RunMonitor()
{
while (IsMonitoring)
{
Thread.Sleep(250);
int i = (int)((double)(currprogress / 100) /
(double)maxprogress * 100);
Console.WriteLine("new Progress "+i);

UpdatePositionDelegate u = new
UpdatePositionDelegate(UpdateProgress);
this.Invoke(u, i);
}
}

That delegate is declared as:

public delegate void UpdatePositionDelegate(int progress);

and the UpdatePorgress method it invokes on the Form (this) is:

private void UpdateProgress(int val)
{
progress.Value = val;
statusStrip1.Refresh();
}


But it's not working.

It goes through RunMonitor once and hangs on the call to UpdateProgress the
whole time the file is loaded, so never updates the progress bar.

What could be wrong? Why does it hang?
 
P

Peter Duniho

trant said:
I have a Form with a progress bar and a thread that should update the
progress every quarter of a second. The operation being monitored for
progress on is a file loading job.

So I start off the monitor like this:

long currprogress = 0;
FileInfo info = new FileInfo(currFile);
long maxprogress = info.Length / 100;
bool IsMonitoring = true;
Thread monitor = new Thread(new ThreadStart(RunMonitor));
monitor.Start();

(the scope of these variables is class level though, just made them local
scope for easier reading)

Then my RunMonitor method looks like:

private void RunMonitor()
{
while (IsMonitoring)
{
Thread.Sleep(250);
int i = (int)((double)(currprogress / 100) /
(double)maxprogress * 100);
Console.WriteLine("new Progress "+i);

UpdatePositionDelegate u = new
UpdatePositionDelegate(UpdateProgress);
this.Invoke(u, i);
}
}

That delegate is declared as:

public delegate void UpdatePositionDelegate(int progress);

and the UpdatePorgress method it invokes on the Form (this) is:

private void UpdateProgress(int val)
{
progress.Value = val;
statusStrip1.Refresh();
}


But it's not working.

It goes through RunMonitor once and hangs on the call to UpdateProgress the
whole time the file is loaded, so never updates the progress bar.

What could be wrong? Why does it hang?

Since you failed to post a concise-but-complete code example that
reliably demonstrates the problem, there's no way for anyone to say for
sure.

But, I would guess that you are still executing your lengthy operation
on the main GUI thread. Which means the main GUI thread is blocked from
processing the implicit cross-thread invoke when you assign the new
"val" value to the "progress.Value" property. That can't complete until
the main thread is available to execute the invoked assignment, and that
won't happen until the operation is actually done.

Basically, your whole
 
P

Peter Duniho

trant said:
I have a Form with a progress bar and a thread that should update the
progress every quarter of a second. The operation being monitored for
progress on is a file loading job.

[...]
It goes through RunMonitor once and hangs on the call to
UpdateProgress the whole time the file is loaded, so never updates the
progress bar.
What could be wrong? Why does it hang?

Since you failed to post a concise-but-complete code example that
reliably demonstrates the problem, there's no way for anyone to say for
sure.

But, I would guess that you are still executing your lengthy operation
on the main GUI thread. Which means the main GUI thread is blocked from
processing the cross-thread invoke when you try to invoke your
UpdatePositiongDelegate() method. That can't complete until the main
thread is available to execute the invoked assignment, and that won't
happen until the operation is actually done.

Basically, if my guess is correct, your whole implementation is
backwards. The whole point of using a thread in this situation is so
that the lengthy operation doesn't get executed on the main GUI thread.
But all you seem to have done is put some polling in a separate
thread, and left the lengthy operation on the main GUI thread.

So, not only have you not avoided blocking the main GUI thread, you've
_also_ added polling to the equation, which is unnecessary and inefficient.

Instead, you should execute your lengthy operation in the separate
thread, and then update the progress from within the lengthy operation
itself.

Pete
 
T

trant

Nevermind, sorry about this. I realized my embarassing misunderstanding...
the Form's thread was the one loading the file! I delegated that work to a
new thread and now everything is behaving as expected.

Thanks!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top