Progress bar causes application lockup

J

JoeB

Hi,

This is 100% reproducable. .NetCF / WinCE5.0 / VS.Net 2003

1. Create a new 'smart device application' project.

2. Add a progress bar to the form 'progressBar1'

3..Add: using System.Threading; to the top of the code.

4. Add this in Form1() after the call to InitializeComponent()

System.Threading.ThreadStart ts = null;
ts = new System.Threading.ThreadStart( CycleProgressBar );
System.Threading.Thread t = new System.Threading.Thread( ts );
t.Start();


5. Add this to the class:

private void CycleProgressBar()
{
Thread.Sleep(2000);
int x = 0;
while( true )
{
progressBar1.Value = x;
x+= 10;
if( ++x > 100 )
{
x = 0;
}
Thread.Sleep(200);
}
}



Now deploy.-- When the app starts the porgress bar wil start to cycle.
wiggle the mouse over the progress bar, and the application locks dead!

How can i stop this bug?!



Joe
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

First of all, there is a group dedicated to the compact framework:
microsoft.public.dotnet.framework.compactframework , you should post
questions there

The problem you have though is very easy to solve, you cannot access a UI
control from a thread, you have to use Control.Invoke to force the method to
execute in the control's thread.




cheers,
 
J

JoeB

Hi,

You've gone past my knolodge of the language, i've looked at the docs for
Invoke and it wants a delegate as a param, so i tried

progressBar1.Invoke( progressBar1.value = x )

and got an error.

Can you tell me how to do it? Is it simple??




j
 
S

Stoitcho Goutsev \(100\) [C# MVP]

JoeB,



I'm not sure about CF, but in normal windows forms application this code is
most likely will lock up because you are modifying control from thread
different than the thread created the control. The correct way is to use
Control.InvokeRequired and Control.Invoke to marshal the code to the UI
thread.



I see that Control.InvokeRequired is not supported for CF in .NET 1.x, but
has been added in .NET 2.0, which makes me believe that the problem exist
for CF too.



Control.Invoke is supported in both platforms, so go ahead and use it. Let
only the UI thread modify properties and call methods of controls.




HTH

Stoitcho Goutsev (100) [C# MVP]
 
J

JoeB

OK,

I've been playing with the code, and now i have this:
(the thread start in form1() remains the same)



private delegate void DelegateStarter();
private void CycleProgressBar()
{
Thread.Sleep(2000);
DelegateStarter dls = new DelegateStarter( _CycleProgressBar );
progressBar1.Invoke( dls );
}

private void _CycleProgressBar()
{
int x = 0;
while( true )
{
progressBar1.Value = x;
x += 10;
if( x > 100 )
x = 0;

Thread.Sleep(200);
}
}



But when the Invoke(..) is called, i get an exception saying invalid param.




j



Stoitcho Goutsev (100) said:
JoeB,



I'm not sure about CF, but in normal windows forms application this code
is most likely will lock up because you are modifying control from thread
different than the thread created the control. The correct way is to use
Control.InvokeRequired and Control.Invoke to marshal the code to the UI
thread.



I see that Control.InvokeRequired is not supported for CF in .NET 1.x, but
has been added in .NET 2.0, which makes me believe that the problem exist
for CF too.



Control.Invoke is supported in both platforms, so go ahead and use it. Let
only the UI thread modify properties and call methods of controls.




HTH

Stoitcho Goutsev (100) [C# MVP]



JoeB said:
Hi,

This is 100% reproducable. .NetCF / WinCE5.0 / VS.Net 2003

1. Create a new 'smart device application' project.

2. Add a progress bar to the form 'progressBar1'

3..Add: using System.Threading; to the top of the code.

4. Add this in Form1() after the call to InitializeComponent()

System.Threading.ThreadStart ts = null;
ts = new System.Threading.ThreadStart( CycleProgressBar );
System.Threading.Thread t = new System.Threading.Thread( ts );
t.Start();


5. Add this to the class:

private void CycleProgressBar()
{
Thread.Sleep(2000);
int x = 0;
while( true )
{
progressBar1.Value = x;
x+= 10;
if( ++x > 100 )
{
x = 0;
}
Thread.Sleep(200);
}
}



Now deploy.-- When the app starts the porgress bar wil start to cycle.
wiggle the mouse over the progress bar, and the application locks dead!

How can i stop this bug?!



Joe
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

Try this code ( I wrote it here, so it may have erros ) , if not look into
the archives for "Control.Invoke" you will find plenty of info

delegate void UpdateBarHandler( int size);

void UpdateBar( int size )
{
progressBar1.Value = size;
}


private void CycleProgressBar()
{
Thread.Sleep(2000);
int x = 0;
while( true )
{
progressBar1.Invoke( new UpdateBarHandler( UpdateBar), new object[]
{ 10 } );
x+= 10;
if( ++x > 100 )
{
x = 0;
}
Thread.Sleep(200);
}
}
 
J

JoeB

Hi,

Im using the .netCF and it doesnt support the 2nd param of Invoke.



j


Ignacio Machin ( .NET/ C# MVP ) said:
Hi,

Try this code ( I wrote it here, so it may have erros ) , if not look into
the archives for "Control.Invoke" you will find plenty of info

delegate void UpdateBarHandler( int size);

void UpdateBar( int size )
{
progressBar1.Value = size;
}


private void CycleProgressBar()
{
Thread.Sleep(2000);
int x = 0;
while( true )
{
progressBar1.Invoke( new UpdateBarHandler( UpdateBar), new object[]
{ 10 } );
x+= 10;
if( ++x > 100 )
{
x = 0;
}
Thread.Sleep(200);
}
}

JoeB said:
Hi,

You've gone past my knolodge of the language, i've looked at the docs for
Invoke and it wants a delegate as a param, so i tried

progressBar1.Invoke( progressBar1.value = x )

and got an error.

Can you tell me how to do it? Is it simple??




j
 
J

JoeB

i've solved the porblem, i have a global var that holds the required
progress bar value, then Invoke a single delegate that reads the value.

private int ProgressBarValue = 0;

private void _UpdateProgressBar( object sender, EventArgs e )
{
ProgressBar.Value = ProgressBarValue;
}

private void UpdateProgressBar( int iPercent )
{
if( iPercent > 100 )
iPercent = 100;
else if( iPercent < 0 )
iPercent = 0;

ProgressBarValue = iPercent;
ProgressBar.Invoke( new EventHandler(_UpdateProgressBar) );
}

private void CycleProgressBar()
{
int x = 0;
while( bCycleProgressBarRunning )
{
UpdateProgressBar( 10 * x );
if( ++x > 10 )
x = 0;

Thread.Sleep(200);
}
UpdateProgressBar(0);
}

Thanks



j

JoeB said:
Hi,

Im using the .netCF and it doesnt support the 2nd param of Invoke.



j


Ignacio Machin ( .NET/ C# MVP ) said:
Hi,

Try this code ( I wrote it here, so it may have erros ) , if not look
into the archives for "Control.Invoke" you will find plenty of info

delegate void UpdateBarHandler( int size);

void UpdateBar( int size )
{
progressBar1.Value = size;
}


private void CycleProgressBar()
{
Thread.Sleep(2000);
int x = 0;
while( true )
{
progressBar1.Invoke( new UpdateBarHandler( UpdateBar), new
object[] { 10 } );
x+= 10;
if( ++x > 100 )
{
x = 0;
}
Thread.Sleep(200);
}
}

JoeB said:
Hi,

You've gone past my knolodge of the language, i've looked at the docs
for Invoke and it wants a delegate as a param, so i tried

progressBar1.Invoke( progressBar1.value = x )

and got an error.

Can you tell me how to do it? Is it simple??




j



"Ignacio Machin ( .NET/ C# MVP )" <ignacio.machin AT dot.state.fl.us>
wrote in message Hi,

First of all, there is a group dedicated to the compact framework:
microsoft.public.dotnet.framework.compactframework , you should post
questions there

The problem you have though is very easy to solve, you cannot access a
UI control from a thread, you have to use Control.Invoke to force the
method to execute in the control's thread.




cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation



Hi,

This is 100% reproducable. .NetCF / WinCE5.0 / VS.Net 2003

1. Create a new 'smart device application' project.

2. Add a progress bar to the form 'progressBar1'

3..Add: using System.Threading; to the top of the code.

4. Add this in Form1() after the call to InitializeComponent()

System.Threading.ThreadStart ts = null;
ts = new System.Threading.ThreadStart( CycleProgressBar );
System.Threading.Thread t = new System.Threading.Thread( ts );
t.Start();


5. Add this to the class:

private void CycleProgressBar()
{
Thread.Sleep(2000);
int x = 0;
while( true )
{
progressBar1.Value = x;
x+= 10;
if( ++x > 100 )
{
x = 0;
}
Thread.Sleep(200);
}
}



Now deploy.-- When the app starts the porgress bar wil start to
cycle. wiggle the mouse over the progress bar, and the application
locks dead!

How can i stop this bug?!



Joe
 
S

Stoitcho Goutsev \(100\) [C# MVP]

JoeB,

I see you solved your problem. Is that correct?


--

Stoitcho Goutsev (100) [C# MVP]
JoeB said:
OK,

I've been playing with the code, and now i have this:
(the thread start in form1() remains the same)



private delegate void DelegateStarter();
private void CycleProgressBar()
{
Thread.Sleep(2000);
DelegateStarter dls = new DelegateStarter( _CycleProgressBar );
progressBar1.Invoke( dls );
}

private void _CycleProgressBar()
{
int x = 0;
while( true )
{
progressBar1.Value = x;
x += 10;
if( x > 100 )
x = 0;

Thread.Sleep(200);
}
}



But when the Invoke(..) is called, i get an exception saying invalid
param.




j



Stoitcho Goutsev (100) said:
JoeB,



I'm not sure about CF, but in normal windows forms application this code
is most likely will lock up because you are modifying control from thread
different than the thread created the control. The correct way is to use
Control.InvokeRequired and Control.Invoke to marshal the code to the UI
thread.



I see that Control.InvokeRequired is not supported for CF in .NET 1.x,
but has been added in .NET 2.0, which makes me believe that the problem
exist for CF too.



Control.Invoke is supported in both platforms, so go ahead and use it.
Let only the UI thread modify properties and call methods of controls.




HTH

Stoitcho Goutsev (100) [C# MVP]



JoeB said:
Hi,

This is 100% reproducable. .NetCF / WinCE5.0 / VS.Net 2003

1. Create a new 'smart device application' project.

2. Add a progress bar to the form 'progressBar1'

3..Add: using System.Threading; to the top of the code.

4. Add this in Form1() after the call to InitializeComponent()

System.Threading.ThreadStart ts = null;
ts = new System.Threading.ThreadStart( CycleProgressBar );
System.Threading.Thread t = new System.Threading.Thread( ts );
t.Start();


5. Add this to the class:

private void CycleProgressBar()
{
Thread.Sleep(2000);
int x = 0;
while( true )
{
progressBar1.Value = x;
x+= 10;
if( ++x > 100 )
{
x = 0;
}
Thread.Sleep(200);
}
}



Now deploy.-- When the app starts the porgress bar wil start to cycle.
wiggle the mouse over the progress bar, and the application locks dead!

How can i stop this bug?!



Joe
 
J

JoeB

yeah, thanks for everyones help!



j




Stoitcho Goutsev (100) said:
JoeB,

I see you solved your problem. Is that correct?


--

Stoitcho Goutsev (100) [C# MVP]
JoeB said:
OK,

I've been playing with the code, and now i have this:
(the thread start in form1() remains the same)



private delegate void DelegateStarter();
private void CycleProgressBar()
{
Thread.Sleep(2000);
DelegateStarter dls = new DelegateStarter( _CycleProgressBar );
progressBar1.Invoke( dls );
}

private void _CycleProgressBar()
{
int x = 0;
while( true )
{
progressBar1.Value = x;
x += 10;
if( x > 100 )
x = 0;

Thread.Sleep(200);
}
}



But when the Invoke(..) is called, i get an exception saying invalid
param.




j



Stoitcho Goutsev (100) said:
JoeB,



I'm not sure about CF, but in normal windows forms application this code
is most likely will lock up because you are modifying control from
thread different than the thread created the control. The correct way is
to use Control.InvokeRequired and Control.Invoke to marshal the code to
the UI thread.



I see that Control.InvokeRequired is not supported for CF in .NET 1.x,
but has been added in .NET 2.0, which makes me believe that the problem
exist for CF too.



Control.Invoke is supported in both platforms, so go ahead and use it.
Let only the UI thread modify properties and call methods of controls.




HTH

Stoitcho Goutsev (100) [C# MVP]



Hi,

This is 100% reproducable. .NetCF / WinCE5.0 / VS.Net 2003

1. Create a new 'smart device application' project.

2. Add a progress bar to the form 'progressBar1'

3..Add: using System.Threading; to the top of the code.

4. Add this in Form1() after the call to InitializeComponent()

System.Threading.ThreadStart ts = null;
ts = new System.Threading.ThreadStart( CycleProgressBar );
System.Threading.Thread t = new System.Threading.Thread( ts );
t.Start();


5. Add this to the class:

private void CycleProgressBar()
{
Thread.Sleep(2000);
int x = 0;
while( true )
{
progressBar1.Value = x;
x+= 10;
if( ++x > 100 )
{
x = 0;
}
Thread.Sleep(200);
}
}



Now deploy.-- When the app starts the porgress bar wil start to cycle.
wiggle the mouse over the progress bar, and the application locks dead!

How can i stop this bug?!



Joe
 

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