Если вы решите использовать C # async / await, вы должны перейти к правильному потоку перед вызовом любого async
метода.Поставьте точку останова на начало метода в вашем вопросе - до того, как он вызовет BeginInvoke.Поднимайтесь по стеку вызовов, пока не получите метод, который не объявлен async
. То, что - это метод , который должен выполнять BeginInvokeOnMainThread
в качестве обертки вокруг всех вашего асинхронного кода.
Обязательно удалите BeginInvokeOnMainThread
из кода, который вы показали - как только вы окажетесь внутри async/await
, это не будет делать то, что вы хотите.
ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Было бы лучше вместо этого сделать фундаментальное изменение в другом месте.
Почему вы находитесь в фоновом потоке, но вам требуется вызов пользовательского интерфейса?
Существует множество механизмов разделенияВаш код в часть пользовательского интерфейса и часть фона: вы еще не сделали этого полностью, иначе у вас не возникнет этой проблемы.
Возможно, вам нужна фоновая задача с обратным вызовом прогресса.Этот обратный вызов связывается с пользователем по мере необходимости.
Или вам нужен отчет о завершении фоновой задачи вашему основному коду, что она не может продолжаться без ввода пользователя, введите пользовательский код в этом основном коде, затем запустите другую фоновую задачу, чтобы завершитьwork .
Или ранее в вашем коде, прежде чем начинать фоновое задание, вам нужно было проверить, что вы получили всю необходимую информацию от пользователя, и связаться с ней.
Если это не такЕсли намеков на то, чтобы направить вас в рабочее русло, я рекомендую найти более полный пример async / await, используемого в приложении, изучить его работу.Если у вас все еще есть этот вопрос, добавьте к нему более подробную информацию.
Это «чистый» ответ.
На практике мне иногда бывает проще добавить BeginInvokeOnMainThread
- и затем напишите код без асинхронности / ожидания .
Г.Хаким сделал существенное наблюдение:
DisplayAlert являетсяМетод возврата задачи ...
См. Документация Microsoft - Цепочка задач с помощью задач продолжения Если вы хотите понять, как вызывать DisplayAlert, затем выполните что-то еще.
Идя по этому пути, я думаю, вам нужно удалить async
и await
из вашего метода.Вы будете выполнять «асинхронный» вызов самостоятельно.
Вместо того, чтобы пытаться выполнить работу после возвращения этого метода, вы передадите параметр с работой, которая будет выполнена дальше.Что-то вроде:
public void ShowMessageBoxAsync(string message, Action afterAction)
{
Device.BeginInvokeOnMainThread(() =>
{
// See "Chaining Tasks ..." link. Use "afterAction" as "continuation".
... DisplayAlert("Error", message, "OK", "Cancel") ...
});
}
«afterAction» - это то, что станет «продолжением».
Извините, у меня нет подробностей - см. Ссылку выше.