Dela via


CoreDispatcher.RunAsync(CoreDispatcherPriority, DispatchedHandler) Method

Definition

Schedules the provided callback on the UI thread from a worker thread, and returns the results asynchronously.

public:
 virtual IAsyncAction ^ RunAsync(CoreDispatcherPriority priority, DispatchedHandler ^ agileCallback) = RunAsync;
/// [Windows.Foundation.Metadata.RemoteAsync]
IAsyncAction RunAsync(CoreDispatcherPriority const& priority, DispatchedHandler const& agileCallback);
[Windows.Foundation.Metadata.RemoteAsync]
public IAsyncAction RunAsync(CoreDispatcherPriority priority, DispatchedHandler agileCallback);
function runAsync(priority, agileCallback)
Public Function RunAsync (priority As CoreDispatcherPriority, agileCallback As DispatchedHandler) As IAsyncAction

Parameters

priority
CoreDispatcherPriority

Specifies the priority for event dispatch. Set this to CoreDispatcherPriority.Normal.

agileCallback
DispatchedHandler

The callback on which the dispatcher returns when the event is dispatched.

Returns

The object that provides handlers for the completed async event dispatch.

Attributes

Examples

The following examples demonstrate the use of Dispatcher.RunAsync to schedule work on the main UI thread using the CoreWindow's event dispatcher.

await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
   rootPage.NotifyUser("The toast encountered an error", NotifyType.ErrorMessage);
});

var ignored = Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
   Scenario3OutputText.Text += outputText;
});
TimerTextBlock().Dispatcher().RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, [=]()
{
    ++m_count;
    std::wstringstream wstringstream;
    wstringstream << L"Total count: " << m_count;
    TimerTextBlock().Text(wstringstream.str().c_str());
});
// 
_Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, 
                     ref new Windows::UI::Core::DispatchedHandler([this]()
{
  _count++;
  TimerTextBlock->Text = "Total Running Time: " + _count.ToString() + " Seconds";
}));

// using CallbackContext::Any
void Playback::DisplayStatus(Platform::String^ text)
{
  _Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, 
                        ref new Windows::UI::Core::DispatchedHandler([=]()
  {
    _OutputStatus->Text += text + "\n";
  }, CallbackContext::Any)); 
}

Remarks

If you're on a worker thread, and you want to schedule work on the UI thread, use CoreDispatcher.RunAsync. Always set the priority to CoreDispatcherPriority.Normal or CoreDispatcherPriority.Low, and ensure that any chained callbacks also use CoreDispatcherPriority.Normal or CoreDispatcherPriority.Low.

Note

Callbacks scheduled with CoreDispatcherPriority.Low priority are called when there are no pending input events. Use the CoreDispatcherPriority.Low priority to make your app UI more responsive. To schedule background tasks, use CoreDispatcher.RunIdleAsync.

To spin off a worker thread from the UI thread, do not use this method (CoreDispatcher.RunAsync). Instead, use one of the Windows.System.Threading.ThreadPool.RunAsync method overloads.

This method completes successfully when the CoreDispatcher starts to shut down, but does not run the specified callback on the UI thread. Use CoreDispatcher.TryRunAsync if you need to detect this case.

C++/WinRT. An alternative to CoreDispatcher.RunAsync is winrt::resume_foreground.

Await a UI task sent from a background thread

When you update your UI from a background thread by calling RunAsync, it schedules the work on the UI thread, and returns control to the caller immediately. If you need to wait for async work to complete before returning, for example, waiting for user input in a dialog box, do not use RunAsync alone. RunAsync also doesn't provide a way for the task to return a result to the caller.

In this C# example, RunAsync returns without waiting for the user input from the dialog box. (RunAsync returns as soon as the code in the lambda expression begins executing.)

//DO NOT USE THIS CODE.

await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
{
   await signInDialog.ShowAsync(); 
});
// Execution continues here before the call to ShowAsync completes.

In this case, for C#, you need to use a TaskCompletionSource in combination with RunAsync to return a Task that you can await from your background thread, thereby pausing execution until the UI task completes.

public async Task<ContentDialogResult> SignInAsync()
{
    TaskCompletionSource<ContentDialogResult> taskCompletionSource = 
        new TaskCompletionSource<ContentDialogResult>();

    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
    {
        try
        {
            taskCompletionSource.SetResult(await signInDialog.ShowAsync());
        }
        catch (Exception ex)
        {
            taskCompletionSource.SetException(ex);
        }
    });

    return await taskCompletionSource.Task;
}

Tip

We recommend that you use the RunTaskAsync extension method from our task snippet library for this. It provides a robust solution that enables code running on a background thread to await a task that must run on the UI thread. See the Await a UI task sent from a background thread page for the code and example usage.

C++/WinRT. TaskCompletionSource is not available to C++/WinRT. For alternative options, see A completion source sample.

Porting from .NET

If you're porting from .NET code, and using Dispatcher.BeginInvoke and Dispatcher.Invoke methods, note that CoreDispatcher.RunAsync is asynchronous. There is no synchronous version. After you change Dispatcher.Invoke to CoreDispatcher.RunAsync, your code must support the Windows Runtime async pattern, and use the specific lambda syntax for your chosen language.

Applies to

See also