Bastiflew
Bastiflew

Reputation: 1166

Invoke failed in a task

I have this code :

var task = System.Threading.Tasks.Task.Factory.StartNew(() =>
{
    // Code...
    Invoke(new Action(() => progressBar.Increment(1)));
    // Code...
});

task.Wait();

But the Invoke fail, without Exception or any kind of error. It seems that the "wait" prevents the refresh of the form, probably because I'm still in the method.

how do I get around this?

Thanks

Upvotes: 2

Views: 3314

Answers (2)

Jeroen van Langen
Jeroen van Langen

Reputation: 22038

You got yourself a dead-lock.

When the Task is running (on a different thread) and you call Invoke, it wants to invoke it on the mainthread. But the mainthread is waiting for the Task to complete... (task.Wait() will block until it's ready)

What if you use:

await task;

The method using this code should be marked as async. The compiler will cut the method into pieces, and while waiting, the messageloop/thread runs again. When the task is ready, the rest of the method will be executed. (below the await task;)


Look here for more info: await vs Task.Wait - Deadlock?

Upvotes: 4

Alden
Alden

Reputation: 6703

This is a deadlock. The UI thread is blocking on the task.Wait() line, waiting for the task to finish. The task is blocking on Invoke because it needs to tell the UI thread to update the progress bar.

You should NOT be waiting for a task to complete on the UI thread, and should remove task.Wait(). The UI will update as soon as the task finishes.

Any code you were going to put below task.Wait() should go inside the Invoke action:

var task = System.Threading.Tasks.Task.Factory.StartNew(() =>
{
    // do task work

    Invoke(new Action(() => {
        progressBar.Increment(1);
        // other code that needs the task to be finished should go here
    }));
});

// don't call task.Wait() here

Upvotes: 3

Related Questions