CoreDispatcher.RunAsync(CoreDispatcherPriority, DispatchedHandler) Метод
Определение
Важно!
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Планирует предоставленный обратный вызов в потоке пользовательского интерфейса из рабочего потока и возвращает результаты асинхронно.
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
Параметры
- priority
- CoreDispatcherPriority
Указывает приоритет для диспетчеризации событий. Задайте для этого параметра значение CoreDispatcherPriority.Normal.
- agileCallback
- DispatchedHandler
Обратный вызов, который диспетчер возвращает при отправке события.
Возвращаемое значение
Объект , предоставляющий обработчики для завершенной асинхронной отправки событий.
- Атрибуты
Примеры
В следующих примерах показано использование Dispatcher.RunAsync для планирования работы в потоке пользовательского интерфейса main с помощью диспетчера событий CoreWindow.
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));
}
Комментарии
Если вы работаете в рабочем потоке и хотите запланировать работу в потоке пользовательского интерфейса, используйте CoreDispatcher.RunAsync. Всегда устанавливайте приоритет CoreDispatcherPriority.Normal или CoreDispatcherPriority.Low и убедитесь, что все связанные обратные вызовы также используют CoreDispatcherPriority.Normal или CoreDispatcherPriority.Low.
Примечание
Обратные вызовы, запланированные с приоритетом CoreDispatcherPriority.Low , вызываются при отсутствии ожидающих входных событий. Используйте приоритет CoreDispatcherPriority.Low , чтобы сделать пользовательский интерфейс приложения более быстрым. Для планирования фоновых задач используйте CoreDispatcher.RunIdleAsync.
Чтобы отключить рабочий поток из потока пользовательского интерфейса, не используйте этот метод (CoreDispatcher.RunAsync). Вместо этого используйте одну из перегрузок метода Windows.System.Threading.ThreadPool.RunAsync .
Этот метод успешно завершается, когда CoreDispatcher начинает работу, но не выполняет указанный обратный вызов в потоке пользовательского интерфейса. Если необходимо обнаружить этот случай, используйте CoreDispatcher.TryRunAsync .
C++/WinRT. Альтернативой CoreDispatcher.RunAsync является winrt::resume_foreground.
Ожидание задачи пользовательского интерфейса, отправленной из фонового потока
При обновлении пользовательского интерфейса из фонового потока путем вызова RunAsync он планирует работу в потоке пользовательского интерфейса и немедленно возвращает управление вызывающему объекту. Если вам нужно дождаться завершения асинхронной работы перед возвратом, например, дожидаясь ввода данных пользователем в диалоговом окне, не используйте RunAsync в одиночку. RunAsync также не позволяет задаче возвращать результат вызывающему объекту.
В этом примере на C# функция RunAsync возвращает данные, не дожидаясь ввода пользователем из диалогового окна. (RunAsync возвращает, как только код в лямбда-выражении начинает выполняться.)
//DO NOT USE THIS CODE.
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
{
await signInDialog.ShowAsync();
});
// Execution continues here before the call to ShowAsync completes.
В этом случае для C# необходимо использовать TaskCompletionSource в сочетании с RunAsync, чтобы вернуть задачу, которую можно ожидать из фонового потока, тем самым приостанавливая выполнение до завершения задачи пользовательского интерфейса.
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;
}
Совет
Для этого рекомендуется использовать метод расширения RunTaskAsync из библиотеки фрагментов задач. Он предоставляет надежное решение, позволяющее коду, выполняемому в фоновом потоке, ожидать выполнения задачи, которая должна выполняться в потоке пользовательского интерфейса. Код и пример использования см. на странице Задачи ожидания пользовательского интерфейса, отправленной из фонового потока .
C++/WinRT. TaskCompletionSource недоступен для C++/WinRT. Дополнительные варианты см. в разделе Пример источника завершения.
Перенос из .NET
Если вы переносите из кода .NET и используете методы Dispatcher.BeginInvoke и Dispatcher.Invoke , обратите внимание, что CoreDispatcher.RunAsync является асинхронным. Синхронная версия отсутствует. После изменения Dispatcher.Invoke на CoreDispatcher.RunAsync код должен поддерживать среда выполнения Windows асинхронный шаблон и использовать конкретный лямбда-синтаксис для выбранного языка.