CBreeze
CBreeze

Reputation: 2983

Async Task Still Blocking UI Thread

I'm reallt trying to get my head around async/await and Tasks. I'm trying to get one method down so that I can use it throughout my program. Basically I have my own version of BusyIndicator that I want to display whilst work is being done. Here is a basic example;

private async void OnPageLoad(object sender, RoutedEventArgs e)
{
    var waitWindow = new PleaseWaitWindow();

    waitWindow.Show();

    await LoadCompanyContracts();

    waitWindow.Close();
}

private async Task LoadCompanyContracts()
{
    await Task.Run(() =>
    {
        Dispatcher.Invoke(() =>
        {
             //Work done here
        });
    });     
}

Even through these two methods and attempting implementing Tasks my BusyIndicator still doesn't rotate, it is displayed but is frozen so in effect I believe the UI thread is still blocked. How can I modify this piece of code to ensure that all CPU bound work is not blocking the UI thread?

Upvotes: 5

Views: 7651

Answers (3)

Stephen Cleary
Stephen Cleary

Reputation: 457422

As a general rule, you shouldn't use Dispatcher at all. It's extremely common practice, but it's a commonly bad practice.

private async Task LoadCompanyContracts()
{
  await Task.Run(() =>
  {
    //Work done here
  });
  // Update UI if necessary.
}

Upvotes: 9

Daniil Vlasenko
Daniil Vlasenko

Reputation: 499

Don't do you work inside Dispatcher.Invoke(), because your dispatcher is associated with ui thread. Do your work inside Task and use dispatcher only for updating UI

    private async Task LoadCompanyContracts()
    {
       await Task.Run(() =>
       {
         /*Work done here
          *
          */
         Dispatcher.Invoke(() =>
         {
             //Update UI 
         });
       });     
     }

Upvotes: 2

OrcusZ
OrcusZ

Reputation: 3660

After looking for some examples in my code here a solution you can try :

    private async void OnPageLoad(object sender, RoutedEventArgs e)
    {
        var waitWindow = new PleaseWaitWindow();

        waitWindow.Show();

        InitLoadCompanyContracts();

        waitWindow.Close();
    }


    private async void InitLoadCompanyContracts(){
        await LoadCompanyContracts();
    }


    private async Task LoadCompanyContracts()
    {
        await Task.Run(() =>
        {
            Dispatcher.Invoke(() =>
            {
                 //Work done here
            });
        });     
    }

I use this to have an awaitable method but out of all "graphics" methods. I don't know if is the best way to do that, but for me it's work.

Upvotes: -3

Related Questions