GameScripting
GameScripting

Reputation: 17002

Form.Invoke freezes the UI

I have been googling around for about an hour, and I still don't found any solution.

I simply try to set the maximum value of a progressbar from another thread. So I found the Control.Invoke method. I've been going ahead and implement it:

enter image description here

Now, when I debug my App it simply stucks at the this.Invoke line. The UI comes up, and it is frozen. So I was going ahead and google that out, and it told me to use this.BeginInvoke(). I implemented it, and I was fine, the UI don't freeze. Thats quiet nice, but in fact the maximum value of my progress bar didn't change :(

What am I doing wrong?

EDIT: Maybe that helps: I am using Parallel.Invoke(); to manage my thread ...

Upvotes: 2

Views: 4648

Answers (5)

8Unlimited8
8Unlimited8

Reputation: 494

In my case, mistake was using join() after starting thread. join() prevents main thread from execution of codes before child thread completion. I removed join() command and moved codes after join() to thread and everything worked fine.

Upvotes: 0

Roly
Roly

Reputation: 1

I had the same problem and thanks to Nicholas' answer I realised I had fallen into the same trap in a GUI app to debug a class used in a windows service. The service class runs most of it's code in a thread. The thread was calling back to a logging procedure when it stopped. I was stopping it using a button, and the logging used invoke to update a textbox. The problem was so simple I kicked myself - the invoke was waiting for the button-click to finish, which was waiting for the class to stop which was waiting for invoke to log that it was stopping (repeat until task-manager end process). Solved by creating a thread in the stop button click, with a threadproc to stop the service class. This meant I had to put more code to update form after the stop in another invoke from the new thread, but that worked ok as it wasn't waiting for the main form thread.

Upvotes: 0

seanzi
seanzi

Reputation: 883

I use something similar below in my application which I use to update the actual value for the progress bar. I have changed it a bit from your example. Give it a whirl and see if it helps :)

    public void SetMax(int value)
    {
        if (this.ProgressBar_status.InvokeRequired)
        {
           this.BeginInvoke(new Action<int>(SetMax), value);
           return;
        }
        this.ProgressBar_status.Maximum = value;
    }

Upvotes: 2

Nick Butler
Nick Butler

Reputation: 24383

Control.Invoke will only block when it is called on a worker thread and the UI thread is blocked.

The code you posted is correct. You must be blocking the UI thread somewhere else.

Upvotes: 5

S2S2
S2S2

Reputation: 8502

I would suggest it is better to use Background worker component which supports reporting progress in the progress bar including other features rather than to call invoke and BeginInvoke. You can find more details about background worker at below MSDN link:

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

Upvotes: 0

Related Questions