xamarin преобразует длительно выполняющуюся процедуру в асинхронную

#xamarin #async-await #task

#xamarin #async-await #задача

Вопрос:

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

Процедура:

 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. Это потому, что ваш doIt метод дает сбой (исключение AndroidRuntimeException). О чем сообщается через logcat ?

2. Вы можете ввести try/catch в метод doIt() , чтобы получить больше информации об ошибке.

3. Я сделал, и это сказало мне то, что мне нужно было знать. Краткая версия: runOnUiThread(() => {//доступ к пользовательскому интерфейсу. Это решило проблему.

4. Отлично! Не забудьте опубликовать это как ответ.

Ответ №1:

Я изменил void longRunningProcedure () на async void, как показано ниже:

асинхронный запуск аннулирует runLongRunningProcedure() {

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

для моего приложения actualProcedure() просто:

     void actualProcedure()
  

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

 bool cancelPressed
  

которая начинается как false

У меня есть кнопка и пункт меню, которые устанавливают значение 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();
        });
  

modifiedData — это переменная типа StringBuilder.

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

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

 if (cancelPressed == true) return
  

На всякий случай я вложил это в try / catch.

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

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

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