locked
Is ThreadPool.RunAsync something to use to make the UI responsive? RRS feed

  • Question

  • Instead of using Dispatcher.RunAsync, which freezes the UI...can we use ThreadPool.RunAsync?

    It seems to work, but when you try and update the UI you get that thread marshaling error.

    Example below. This works, but the BindUserInfo fails because it it updating items in the Xaml...

    await ThreadPool.RunAsync(new WorkItemHandler((IAsyncAction) =>
              _mainViewModel.BindUserInfo()
            ));

    Tuesday, April 23, 2013 9:54 PM

Answers

  • ThreadPool.RunAsync is used to run the handler on a ThreadPool thread. This keeps the UI responsive by moving long running handlers off of the UI thread.

    Since the handler is running in a ThreadPool thread and not on the UI thread it cannot directly interact with UI objects. When it gets to the point where it needs to do so it can call Dispatcher.RunAsync to marshal the UI object call back to the UI thread.

    --Rob

    • Marked as answer by Aaron Xue Wednesday, May 8, 2013 10:02 AM
    Tuesday, April 23, 2013 10:28 PM
    Moderator
  • Update, this worked nice...and no Dispatcher needed...UI was fully responsive...

    string s = "";
    await ThreadPool.RunAsync(new WorkItemHandler((IAsyncAction) =>
      s = _mainViewModel.GimmeString()
    ));
    myTextBox.Text = s;
    • Marked as answer by Aaron Xue Wednesday, May 8, 2013 10:02 AM
    Wednesday, April 24, 2013 1:57 PM

All replies

  • ThreadPool.RunAsync is used to run the handler on a ThreadPool thread. This keeps the UI responsive by moving long running handlers off of the UI thread.

    Since the handler is running in a ThreadPool thread and not on the UI thread it cannot directly interact with UI objects. When it gets to the point where it needs to do so it can call Dispatcher.RunAsync to marshal the UI object call back to the UI thread.

    --Rob

    • Marked as answer by Aaron Xue Wednesday, May 8, 2013 10:02 AM
    Tuesday, April 23, 2013 10:28 PM
    Moderator
  • But then you could do something like this, so a Dispatcher isn't required? Going to try this now.

    string s = "";
    await ThreadPool.RunAsync(new WorkItemHandler((IAsyncAction) =>
                _mainViewModel.GetSomething(ref s)
            ));
    tb.Text = s;

    Wednesday, April 24, 2013 1:43 PM
  • Update, this worked nice...and no Dispatcher needed...UI was fully responsive...

    string s = "";
    await ThreadPool.RunAsync(new WorkItemHandler((IAsyncAction) =>
      s = _mainViewModel.GimmeString()
    ));
    myTextBox.Text = s;
    • Marked as answer by Aaron Xue Wednesday, May 8, 2013 10:02 AM
    Wednesday, April 24, 2013 1:57 PM
  • Yes, if you just need the results of the item and don't need to update progress in the middle then you can just await until the ThreadPool task is finished.

    --Rob

    Wednesday, April 24, 2013 5:46 PM
    Moderator