xamarin конвертирует длительную процедуру в асинхронную - PullRequest
1 голос
/ 10 марта 2019

Мое приложение содержит процедуру, которая может быть длительной.Я хотел бы дать пользователям возможность остановить его.

Процедура:

void longRunningProcedure()

(он не имеет доступа к файловой системе или Интернету)

Ивнутри него, как только определенные переменные инициализируются, он вызывает doIt ();

Я пробовал это:

async void longRunningProcedure()

и в рамках этой процедуры я попытался:

await Task.Run(() => doIt());

и попытался:

 await Task.Run(async () => await doIt());

Но когда код достигает этой точки, я получаю эту ошибку:

 The selected debug engine does not support any code executing on the current thread (e.g. only native runtime code is executing).


Unhandled Exception:

Android.Util.AndroidRuntimeException: <Timeout exceeded getting exception details> occurred

Длительный код даже не запускается.

Что делать?

1 Ответ

0 голосов
/ 14 марта 2019

Я изменил void longRunningProcedure () на асинхронный void, как показано ниже:

async void runLongRunningProcedure () {

    await Task.Run(() => actualProcedure());

для моего приложения, фактическая процедура () просто:

    void actualProcedure()

Теперь, кроме этого кода, у меня есть переменная,

bool cancelPressed

который начинается как ложный

У меня есть кнопка и пункт меню, который устанавливает ее в значение true при нажатии или нажатии.

И это все работает. Я могу начать процедуру и остановить ее нажатием кнопки или меню.

Была еще одна проблема: длительная процедура записывает данные в одно из текстовых полей приложения.

Это привело к этой ошибке:

The selected debug engine does not support any code executing on the current thread (e.g. only native runtime code is executing).

ТАК, мне пришлось изменить раздел записи данных следующим образом:

RunOnUiThread( () => {
                txtBox.Text += modifiedData.ToString();
        });

ifiedData - тип переменной типа StringBuilder.

И это все работает.

В соответствующий момент во время процедуры у меня есть:

if (cancelPressed == true) return

Чтобы быть в безопасности, я вложил это в try / catch.

Конечно, если я хотел уведомить пользователя, что процедура была отменена (или что-то еще, пока она выполняется), через сообщение Toast, я должен сделать это:

RunOnUiThread(() => {
                MakeToast(Message);
                return;
            }); 

У меня есть процедура MakeToast, которая обрабатывает форматирование сообщения и т. Д.

...