Simple WinForm ( Not Responding ) Refesh Issue C# 2.0

O

OZI

hello again,


I have a WinForm that can process 100s to 1000s of images.

On the WinForm I have a progress bar, a Label and a Button.

when I click on the process button the progress bar works fine/refreshes
until

If I open a window's explorer window in front of my Form then move it out
of the way, No refresh is happening in my Form ( the progress bar does not
move, but program still working ok)
or
If I move my Form around by dragging it, I get ( Not Responding) in the
title of the Form window

But the Processing continues until the end with no problem.

I have refresh code in my Form inside my Loop where I process a picture
and update my ProgressBar info.

I am not opening any Other Forms or Dialogs. Just one Form only.

do I need to Multi-Thread this one?

what is going on? can someone explain?

Thank you,

OZI
 
C

Chris Shepherd

OZI said:
do I need to Multi-Thread this one?
Yes.

what is going on? can someone explain?

If everything is working on the application's UI thread, then no redraws
will occur until it is finished the work. I'd recommend looking into a
BackgroundWorker as it has the mechanisms necessary to report progress
updates and, can be easily tied to a progress bar. If you're doing a lot
more advanced stuff, you may want to check out a work queuing model.

Chris.
 
O

OZI

Chris,

Can you give me an explanation why when I drag my Form it goes into a
Non-Responding "Mode".
When I click my Process Button, Not touch anything, just sit there and watch
it, everything works fine, My progress Bar is updating and showing the
Progress until the Form is moved or loses it focus.

Also can you please direct me to an example of how to create, use, and
update the UI from another "Worker" Thread.

thank you for your help.

OZI
 
P

Peter Duniho

OZI said:
Can you give me an explanation why when I drag my Form it goes into a
Non-Responding "Mode".
When I click my Process Button, Not touch anything, just sit there and watch
it, everything works fine, My progress Bar is updating and showing the
Progress until the Form is moved or loses it focus.

It would be difficult to explain why you get some updating even when the
processing is in the same thread as the UI, unless you can post a
concise-but-complete example of code that demonstrates that behavior.

Suffice to say, however, that lengthy processing should not be in the
same thread that owns your UI objects, whether it works some of the time
or not.
Also can you please direct me to an example of how to create, use, and
update the UI from another "Worker" Thread.

Both Chris and I have mentioned the BackgroundWorker class. You should
start by looking at the MSDN documentation for that class, as well as
searching this newsgroup for other threads that discuss the class.
There is already a lot of information out there explaining how it's used.

If after reading that information you still have questions then of
course, please post the specific questions concerned any specific issues
you run into.

Pete
 
M

Morten Wennevik [C# MVP]

Chris,

Can you give me an explanation why when I drag my Form it goes into a
Non-Responding "Mode".
When I click my Process Button, Not touch anything, just sit there andwatch
it, everything works fine, My progress Bar is updating and showing the
Progress until the Form is moved or loses it focus.

Also can you please direct me to an example of how to create, use, and
update the UI from another "Worker" Thread.

thank you for your help.

OZI

If you show us your refresh code, we might give you some advice.

Usually doing regular Application.DoEvents() inside your loop gives the application enough time to handle mouse clicks and other user interaction. As Chris mentioned, you can also fire a BackgroundWorker object, which is a simple multithread-class with a few events you need to set up. The code sample below will update a progressbar asynchronously using a BackgroundWorker

BackgroundWorker worker = new BackgroundWorker();
private void Method()
{
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
worker.WorkerReportsProgress = true;
worker.RunWorkerAsync(@"C:\Tempfiles");
}

// Code running inside this method runs in another thread
// If you need to update the GUI thread from here, use Invoke
void worker_DoWork(object sender, DoWorkEventArgs e)
{
string path = (string)e.Argument;
for(int i = 0; i < 200; i++)
{
// Do some work indicated here by sleeping for 200 ms
System.Threading.Thread.Sleep(200);
worker.ReportProgress(i / 2);
}
e.Result = "Work completed";
}

void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}

void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show(e.Result.ToString());
}
 
O

OZI

Peter,

Fair enough. I created a New Test Form with One Button and One progressBar.
See Button Event Below.
When I click on the button and Drag the Form ( try hard to drag it ), then
No Progress is shown, also if you drag it and click anywhere on the Form you
see the No Response in the title of the Form.
There is no intensive Processing here. How can this be explained?
private void button1_Click(object sender, EventArgs e)

{

progressBar1.Maximum = 10;

progressBar1.Minimum = 0;

progressBar1.Value = 0;

progressBar1.Visible = true;

progressBar1.Show();

this.Refresh();

for (int x = 0; x < progressBar1.Maximum ; x++)

{

progressBar1.Increment(1);

System.Threading.Thread.Sleep(1000);

this.Refresh();

}

progressBar1.Visible = false;

progressBar1.Value = 0;

}
 
M

Morten Wennevik [C# MVP]

for (int x = 0; x < progressBar1.Maximum ; x++)

{

progressBar1.Increment(1);

System.Threading.Thread.Sleep(1000);

this.Refresh();

}

Telling the window to refresh itself isn't helping much since you don't give it any time to handle user interaction. If you add Application.DoEvents() after Refresh() (or instead of as you don't need to refresh to update the progress bar) you should see a noticeable difference. Alternately go the BackgroundWorker way (see the code sample in my other reply)..
 
I

Ian Semmel

Well, in this case there will be no response because your app is sleepng
99.9999....% of the time.

Your initial message said you are 'processing' 100's to 1000's of
images. Do you mean your are drawing them ?

Whenever you drag a form, it has to be continually redrawn. If this
drawing is really intensive, you will get no responding messages. What
are you drawing and how are you drawing it ?

-----Original Message-----
From: OZI [mailto:[email protected]]
Posted At: Friday, 14 September 2007 5:07 AM
Posted To: microsoft.public.dotnet.languages.csharp
Conversation: Simple WinForm ( Not Responding ) Refesh Issue C# 2.0
Subject: Re: Simple WinForm ( Not Responding ) Refesh Issue C# 2.0

Peter,

Fair enough. I created a New Test Form with One Button and One
progressBar.
See Button Event Below.
When I click on the button and Drag the Form ( try hard to drag it ),
then
No Progress is shown, also if you drag it and click anywhere on the
Form you
see the No Response in the title of the Form.
There is no intensive Processing here. How can this be explained?
private void button1_Click(object sender, EventArgs e)

{

progressBar1.Maximum = 10;

progressBar1.Minimum = 0;

progressBar1.Value = 0;

progressBar1.Visible = true;

progressBar1.Show();

this.Refresh();

for (int x = 0; x < progressBar1.Maximum ; x++)

{

progressBar1.Increment(1);

System.Threading.Thread.Sleep(1000);

this.Refresh();

}

progressBar1.Visible = false;

progressBar1.Value = 0;

}



Peter Duniho said:
It would be difficult to explain why you get some updating even when the
processing is in the same thread as the UI, unless you can post a
concise-but-complete example of code that demonstrates that behavior.

Suffice to say, however, that lengthy processing should not be in
the
same
thread that owns your UI objects, whether it works some of the time or

Both Chris and I have mentioned the BackgroundWorker class. You should
start by looking at the MSDN documentation for that class, as well as
searching this newsgroup for other threads that discuss the class. There
is already a lot of information out there explaining how it's used.

If after reading that information you still have questions then of course,
please post the specific questions concerned any specific issues you run
into.

Pete
 
O

OZI

Morten,

Application.DoEvents() did everything I need.
You are right I don't need the Refresh();

However, I wish I understand what does that mean. I need help
understanding what does Application.DoEvents() mean and why it solved my
Problem.

I will also look into the BackgroundWorker solution, As soon as I have time
and the "big cheese" goes invisible, I think that would be best on the long
run?

Thank you so much for your help.

OZI



for (int x = 0; x < progressBar1.Maximum ; x++)

{

progressBar1.Increment(1);

System.Threading.Thread.Sleep(1000);

this.Refresh();

}

Telling the window to refresh itself isn't helping much since you don't give
it any time to handle user interaction. If you add Application.DoEvents()
after Refresh() (or instead of as you don't need to refresh to update the
progress bar) you should see a noticeable difference. Alternately go the
BackgroundWorker way (see the code sample in my other reply).
 
M

Morten Wennevik [C# MVP]

Morten,

Application.DoEvents() did everything I need.
You are right I don't need the Refresh();

However, I wish I understand what does that mean. I need help
understanding what does Application.DoEvents() mean and why it solved my
Problem.

I will also look into the BackgroundWorker solution, As soon as I have time
and the "big cheese" goes invisible, I think that would be best on the long
run?

Thank you so much for your help.

OZI

Windows is event driven, which all the little things you see on the user interface is done by firing a whole bunch of various events. However, a regular application is also single threaded, which means executing event handling has to compete with regular code. This works fine in most cases where methods do not do much and is executed within a second or less, which means, if you click a button right after you start a method, the button click might event might not get handled until the one second method is done processing. This becomes very noticeably when the method takes a lot more than one second, making the user interface appear sluggish or non responsive as everything the user does to the interface creates a queue of waiting events (Windows discards windows events that aren't processed within a certain timelimit so the click might not execute at all). This queue will be processed when your method is finished processing. Application.DoEvents() pauses your method and lets the
application process any waiting events, and will continue the method when the events are processed. Calling Application.DoEvents every so often (several times per second) will keep the GUI responsive, and is very handy in a simple loop where each turn does not take much time. If each turn takes too long you need to put the entire loop in a separate thread, which is were the BackgroundWorker comes into play.
 
P

Peter Duniho

OZI said:
[...]
I will also look into the BackgroundWorker solution, As soon as I have time
and the "big cheese" goes invisible, I think that would be best on the long
run?

Hopefully your other questions have been adequately addressed. As far
as the "right way" to do this, yes...BackgroundWorker is much better
than calling DoEvents().

Frankly, I wish people would never mention DoEvents(), or its cousins
Update() and Refresh(). If you have a lengthy task, you just need to
move it out of the path of the UI code. Windows can do a much better
job of managing the multi-tasking than you can, and if you write code
that tries to alternately process UI and process some other task, you
run the risk of one interfering negatively with the other (for example,
DoEvents() is not limited to handling events related to updating your
UI...other events could occur which would potentially cause significant
delay, causing your main processing task to be interfered with).

I hate saying "never", so I'll refrain from saying "_never_ use
DoEvents()". But I think if there's anything in .NET that comes close
to being something that should never be used, DoEvents() is it.

Pete
 
O

OZI

Peter,

Yes with DoEvents if is still a bit sluggish, but for now it is good
enough.
I will, when time permits will go the rout of the BackgroundWorker thread
for sure.
Just need to get my head around it at my own time.

Thanks so much for all your help.

OZI



Peter Duniho said:
OZI said:
[...]
I will also look into the BackgroundWorker solution, As soon as I have
time and the "big cheese" goes invisible, I think that would be best on
the long run?

Hopefully your other questions have been adequately addressed. As far as
the "right way" to do this, yes...BackgroundWorker is much better than
calling DoEvents().

Frankly, I wish people would never mention DoEvents(), or its cousins
Update() and Refresh(). If you have a lengthy task, you just need to move
it out of the path of the UI code. Windows can do a much better job of
managing the multi-tasking than you can, and if you write code that tries
to alternately process UI and process some other task, you run the risk of
one interfering negatively with the other (for example, DoEvents() is not
limited to handling events related to updating your UI...other events
could occur which would potentially cause significant delay, causing your
main processing task to be interfered with).

I hate saying "never", so I'll refrain from saying "_never_ use
DoEvents()". But I think if there's anything in .NET that comes close to
being something that should never be used, DoEvents() is it.

Pete
 
O

OZI

Ian,

What I mean by dragging is I just want to move my from to a better position
on the screen.
when I did that my progress bar stopped working period.

Now it is working with DoEvents() but will move to BackgroundWorker thread
when time permits.

I am processing some pictures and not drawing, each process takes about 2
seconds or less, Nothing intensive like Unsharpen Mask on a 100MB files,
Just very small jpeg pictures less than 100K each. most less than 40K each.

I am unfamiliar with threading and will learn a bit at a time.

Thank you for your response,

OZI


Ian Semmel said:
Well, in this case there will be no response because your app is sleepng
99.9999....% of the time.

Your initial message said you are 'processing' 100's to 1000's of
images. Do you mean your are drawing them ?

Whenever you drag a form, it has to be continually redrawn. If this
drawing is really intensive, you will get no responding messages. What
are you drawing and how are you drawing it ?

-----Original Message-----
From: OZI [mailto:[email protected]]
Posted At: Friday, 14 September 2007 5:07 AM
Posted To: microsoft.public.dotnet.languages.csharp
Conversation: Simple WinForm ( Not Responding ) Refesh Issue C# 2.0
Subject: Re: Simple WinForm ( Not Responding ) Refesh Issue C# 2.0

Peter,

Fair enough. I created a New Test Form with One Button and One
progressBar.
See Button Event Below.
When I click on the button and Drag the Form ( try hard to drag it ),
then
No Progress is shown, also if you drag it and click anywhere on the
Form you
see the No Response in the title of the Form.
There is no intensive Processing here. How can this be explained?
private void button1_Click(object sender, EventArgs e)

{

progressBar1.Maximum = 10;

progressBar1.Minimum = 0;

progressBar1.Value = 0;

progressBar1.Visible = true;

progressBar1.Show();

this.Refresh();

for (int x = 0; x < progressBar1.Maximum ; x++)

{

progressBar1.Increment(1);

System.Threading.Thread.Sleep(1000);

this.Refresh();

}

progressBar1.Visible = false;

progressBar1.Value = 0;

}



Peter Duniho said:
OZI wrote:
Can you give me an explanation why when I drag my Form it goes into a
Non-Responding "Mode".
When I click my Process Button, Not touch anything, just sit there and
watch it, everything works fine, My progress Bar is updating and showing
the Progress until the Form is moved or loses it focus.

It would be difficult to explain why you get some updating even when the
processing is in the same thread as the UI, unless you can post a
concise-but-complete example of code that demonstrates that behavior.

Suffice to say, however, that lengthy processing should not be in
the
same
thread that owns your UI objects, whether it works some of the time or
not.

Also can you please direct me to an example of how to create, use, and
update the UI from another "Worker" Thread.

Both Chris and I have mentioned the BackgroundWorker class. You should
start by looking at the MSDN documentation for that class, as well as
searching this newsgroup for other threads that discuss the class. There
is already a lot of information out there explaining how it's used.

If after reading that information you still have questions then of course,
please post the specific questions concerned any specific issues you run
into.

Pete
 

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