• 0

[VB .NET 2008] Application "not responding mode"


Question

Hello everyone,

I'm having a little headache right now. I have a vn .net 2008 program (.net 4) that does a lot of job in the background. When the user click on a button, the whole form disabled and another form is poped with a progress bar and status information. Then, in the main form, subs and function are ran which send update information to the progress form. Thing is, after a while, the UI thread freeze and the program enter "not responding mode". I've read about doing threads, I tried doing thread but what I want is the main form to stay disabled while the thread is running and the progressform to still be updated.

When using threads, I can't change another thread, it's a protection. So I checked on the web and there is a command to check if the code is ran from the right thread and then change thread if it's not the case and do the job. I've tried these but I get errors.

Then again, for the form to stay disabled, I ran a loop that check if the thread is ended. But then again, it lock up the program.

Thanks

4 answers to this question

Recommended Posts

  • 0

You have to use threading to accomplish your task. The reason the user sees the "not responding" notice is your UI thread is too busy to respond to Window's constant messages to ensure the application is still responding.

Try reading through something like this on threading in .NET.

I haven't read that one as I don't have time at the moment, but if it isn't sufficient it should at least get your feet wet and point you in the right direction.

  • 0

I'd use a background worker to do what you want to do personally. Then just have it bounce back progress to the progress bar, and until the doWorkComplete keep form1.enabled = false.

As for threading, the way I handle cross thread stuff is just invoke what I need done, I make subs that their only purpose is to invoke an update for a label.

ie)


public void UpdateStatusLabel(string msg)
{
try
{
this.Invoke(new MethodInvoker(delegate
{
//Update That label Yo!
lblStatus.Text = msg;
}));
}
catch
{
try
{
//Update That label Yo!
lblStatus.Text = msg;
}
catch (Exception e)
{
//Log what broke
clsMain.Debug.logData("Erroring lblStatus's Caption to: " + msg + ". Error: " + e.Message.ToString(), 1);
}
}
}
[/CODE]

Granted it's C#.. but it works.

  • 0

Ok, it's currently using thread this way:

button click

...

threadImport = New Thread(AddressOf import)

threadImport.SetApartmentState(ApartmentState.MTA)

Me.Enabled = False

threadImport.Start()

threadImport.Join()

Me.Enabled = True

end click

because theadImport isn't part of the same thread as the UI, I can't send the main form (me) the enabled=true command from the thread, it say crossthread operation. Because of that, I use thread.join() to wait for the thread to finish, thus creating a lock.

  • 0

First off, the easy and straight forward way to do this is to simply add the following code in between your hard working method:

Application.DoEvents()

Simply add the Application.DoEvents on the line after you update the progress bar and the method will make windows see that the program is responding.

This is very easy to implement, easy to understand, but also very very limited.

For most applications, you want to do the job (the import) in a separate thread like you have attempted at. There are lots of things you have to remember when working with threads however:

Like you said, threads cannot change UI, because UI elements are only allowed to change through the "UI" thread (the thread that runs when you click a button). To solve this, you have something called delegates which is basicly that your thread tells the UI to run some code next chance it has.

If one thread (like the button click function) has to wait for another thread (your threadImport) you write thread.Join() - this makes the thread lock up and you are back to square one again, UI becomes unresponsive. Unless you have a good reason, stay away from Join().

You have already understood how to run things in their own thread, so here's a link that shows you a bit more about how to update your UI on a separate thread (delegates and invokes and all that fancy stuff). What you need to do is move the Me.Enabled back into the thread using delegates, and remove the threadImport.Join() from your click function.

http://msdn.microsoft.com/en-us/library/zyzhdc6b.aspx

There's a very nice and readable example that should help you understand more about invoke and delegate.

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.