Progress Bar refuses to work?

  • Thread starter Thread starter gwoodhouse
  • Start date Start date
G

gwoodhouse

Hello all, Ive been trying to get a helpful progress bar at the bottom
of my app to simply fill up and then disapear.

Unfortunatly, i get this error message when i try to change the .Value
field of the progress bar: "A first chance exception of type
'System.InvalidOperationException' occurred in
System.Windows.Forms.dll" which may be THE most unhelpful error
message ever.

Here is the code:

private void startNetworkProgressBar()
{
tslReadingFromNetwork.Visible = true;
progressBar.Visible = true;
progressBar.Maximum = 100;
progressBar.Minimum = 0;
progressBar.Step = 10;

progressTimer = new System.Timers.Timer();
progressTimer.Interval = 1000;
progressTimer.Elapsed += new
System.Timers.ElapsedEventHandler(progressTimer_Elapsed);
progressTimer.Start();
}

void progressTimer_Elapsed(object sender,
System.Timers.ElapsedEventArgs e)
{
if (progressBar.Value == 100)
{
tslReadingFromNetwork.Visible = false;
progressBar.Visible = false;
progressTimer.Stop();
}
else
{
progressBar.Value += 10 ;
}
}

Can anyone see why this isnt working? (Ive tried changing the
progressBar.Value +=10 to .performStep() and that gives the same error.
 
Hello all, Ive been trying to get a helpful progress bar at the bottom
of my app to simply fill up and then disapear.

Unfortunatly, i get this error message when i try to change the .Value
field of the progress bar: "A first chance exception of type
'System.InvalidOperationException' occurred in
System.Windows.Forms.dll" which may be THE most unhelpful error
message ever.

Here is the code:

private void startNetworkProgressBar()
{
tslReadingFromNetwork.Visible = true;
progressBar.Visible = true;
progressBar.Maximum = 100;
progressBar.Minimum = 0;
progressBar.Step = 10;

progressTimer = new System.Timers.Timer();
progressTimer.Interval = 1000;
progressTimer.Elapsed += new
System.Timers.ElapsedEventHandler(progressTimer_Elapsed);
progressTimer.Start();
}

void progressTimer_Elapsed(object sender,
System.Timers.ElapsedEventArgs e)
{
if (progressBar.Value == 100)
{
tslReadingFromNetwork.Visible = false;
progressBar.Visible = false;
progressTimer.Stop();
}
else
{
progressBar.Value += 10 ;
}
}

Can anyone see why this isnt working? (Ive tried changing the
progressBar.Value +=10 to .performStep() and that gives the same error.

The Timer is running on a different thread, so when the event handler
runs, it is trying to access progressBar from a thread other than that
it was created on, which is a no-no for UI elements. Read
<http://www.skeet.org.uk/csharp/threads/winforms.shtml> & surrounding
pages for the full story; or for a quick 'don't bother me with details'
fix, change your event handler like so:

void progressTimer_Elapsed(object sender,
System.Timers.ElapsedEventArgs e)
{
this.Invoke((MethodInvoker)delegate
{
if (progressBar.Value == 100)
{
//tslReadingFromNetwork.Visible = false;
progressBar.Visible = false;
progressTimer.Stop();
}
else
{
progressBar.Value += 10;
}
});

All I have done here is wrap your existing code in an anonymous
delegate, which is cast to MethodInvoker (a delegate type for functions
from void to void), and then invoked on the form's thread by the
this.Invoke. This approach requires C# 2.0.
 
Larry,

GREAT tip with the annonymous delegate. That is deffinatly going to be
used in my code:

But my code already invoked the method: Here is the proceeding call:
... [Method on a different thread]..
doubleVoidDelegate doubleVoid= new
doubleVoidDelegate(startNetworkProgressBar);
try { Invoke(doubleVoid); }
catch { }

// Send conscription call.
udpclient.Send(datagram,
datagram.Length);
}
}

private void startNetworkProgressBar()
{

So the methods are already running from an invoke method, and besides
that, the method is allowing me to make the Controls visible and
invisible. Am i missing something (very likley).
 
Using your code does fix the problem though..

The timer is called in my main method, but the timer event is starting
in a different thread...

I don't suppose you could explain why the timer is doing this?

Graeme
PS. Threads confuse me. :)
 
The Timer is running on a different thread, so when the event handler
runs, it is trying to access progressBar from a thread other than that
it was created on, which is a no-no for UI elements. Read
<http://www.skeet.org.uk/csharp/threads/winforms.shtml> & surrounding
pages for the full story; or for a quick 'don't bother me with details'
fix, change your event handler like so:

void progressTimer_Elapsed(object sender,
System.Timers.ElapsedEventArgs e)
{
this.Invoke((MethodInvoker)delegate
{
if (progressBar.Value == 100)
{
//tslReadingFromNetwork.Visible = false;
progressBar.Visible = false;
progressTimer.Stop();
}
else
{
progressBar.Value += 10;
}
});

All I have done here is wrap your existing code in an anonymous
delegate, which is cast to MethodInvoker (a delegate type for functions
from void to void), and then invoked on the form's thread by the
this.Invoke. This approach requires C# 2.0.

--
Larry Lard
(e-mail address removed)
The address is real, but unread - please reply to the group
For VB and C# questions - tell us which version- Hide quoted text -

- Show quoted text -

It's better to avoid Invoke() and to use BeginInvoke() instead.

For more explanation see here: http://kristofverbiest.blogspot.com/2007/02/avoid-invoke-prefer-begininvoke.html
 
Back
Top