broke
broke

Reputation: 8302

Task causing strange behavior in form_load event

I have a task that runs in the form_load event of a usercontrol in winforms:

private void ucDeviceInsert_Load(object sender, EventArgs e)
    {
        System.Threading.Tasks.Task getTBox = System.Threading.Tasks.Task.Run(async () =>
        {
            await AVeryLongRunningProccess();
        });

        pbImage.Image = Properties.Resources.Remove;

        getTBox.Wait();

        pbImage.Image = Properties.Resources.Insert;

        btnNext.Visible = true;

        tmrDeviceInsert.Enabled = true;
        tmrDeviceInsert.Start();
    }

 private void tmrDeviceInsert_Tick(object sender, EventArgs e)
    {
        Next();
    }

I change the image of the picture box to inform the user the progress of the long running process. That part works fine, however the button doesn't show, and the timer never starts. I've stepped through the code, and I can confirm that it is running without any problems, which makes this even more baffling. Any ideas what would be causing this issue?

Upvotes: 1

Views: 61

Answers (2)

Stephen Cleary
Stephen Cleary

Reputation: 456947

Task.Run is for pushing CPU-intensive work off the UI thread. Since you're calling an asynchronous method, I suspect it's not CPU-intensive.

So, you can just use async and await:

private async void ucDeviceInsert_Load(object sender, EventArgs e)
{
  pbImage.Image = Properties.Resources.Remove;
  await AVeryLongRunningProccess();
  pbImage.Image = Properties.Resources.Insert;
  btnNext.Visible = true;
  tmrDeviceInsert.Enabled = true;
  tmrDeviceInsert.Start();
}

Note that at the await, the UI is shown and the user can interact with it (that's the point).

Upvotes: 2

Jacob
Jacob

Reputation: 78890

getTBox.Wait() is going to try to complete that task synchronously. Therefore, the rest of the code after it won't happen until after the task completes.

I'd think you don't want your task to run synchronously at all, but rather handle its completion asynchronously, something like this:

getTBox.ContinueWith(() => updateStatusInUI());

Upvotes: 0

Related Questions