Диалоговое окно прогресса не отображается на .Show() в асинхронном методе

У меня есть асинхронный метод ExecuteWithRetryAsync, который реализует некоторую логику повторения и должен отображать ProgressDialog, как только он вызывается. В настоящее время первый вызов Show() никогда не работает. Диалоговое окно прогресса отображается только после подтверждения AlertDialog (второй комментарий). Как сделать так, чтобы Show() в начале ExecuteWithRetryAsync действительно показывало диалоговое окно прогресса?

  public async Task<object> ExecuteWithRetryAsync(string methodName, object[] args)
  {
MethodInfo methodInfo = typeof(Service1).GetMethod(methodName);

// below progress dialog not showing
mDialog = new ProgressDialog(context);
mDialog.SetMessage("Bitte warten...");
mDialog.SetCancelable(false);
mDialog.Show();

for (; ; )
{
    try
    {
        object result = null;

        try
        {
            // Call web service.
            result = methodInfo?.Invoke(webservice, args);
        }
        catch (TargetInvocationException tie)
        {
            if (tie.InnerException != null) throw tie.InnerException;
        }

        mDialog?.Dismiss();

        return result;
    }
    catch (Exception e)
    {
        Trace.TraceError("Operation Exception");
        currentRetry++;

        if (/*currentRetry > RetryCount || */!IsTransient(e))
        {
            // If this isn't a transient error or we shouldn't retry, 
            // rethrow the exception.
            throw;
        }
    }

    mDialog?.Dismiss();

    await DisplayAlert(
        context.GetString(Resource.String.timeout),
        context.GetString(Resource.String.retry_operation),
        context.GetString(Resource.String.Ok),
        methodInfo);

    // this progress dialog is showing
    mDialog = new ProgressDialog(context);
    mDialog.SetMessage("Bitte warten...");
    mDialog.SetCancelable(false);
    mDialog.Show();

    await Task.Delay(MaxDelayMilliseconds);
}
}

ОБНОВЛЕНИЕ: я заметил, что когда подключение устройства отключено, ExecuteWithRetryAsync требуется около 10-15 секунд, чтобы начать выполнение, и в то же время устройство несколько раз показывает приложение не отвечает диалоговое окно, тогда как при подключении к нему выполняется немедленно. Почему так?

ОБНОВЛЕНИЕ 2: когда я помещаю await Task.Delay (50) после вызова Show(), он отображается, но анимация диалогового окна прогресса не обновляется, она зависает.

ОБНОВЛЕНИЕ 3: я поместил следующую строку result = methodInfo?.Invoke(Utility.WsHueckmann, args) внутри await Task.Run, чтобы она стала await Task.Run(() => { result = methodInfo?.Invoke(Utility.WsHueckmann, args); }), и теперь она работает, и счетчик обновляется.


person bigb055    schedule 11.01.2019    source источник
comment
Причина, по которой это не работает, заключается в том, что при ожидании предупреждения нечего ожидать, диалоговое окно будет отображаться только в том случае, если вы его ждете.   -  person FreakyAli    schedule 11.01.2019
comment
@ G.hakim, вы имеете в виду, что я должен поместить код для отображения диалогового окна прогресса в отдельный метод и вызывать его с помощью ожидания?   -  person bigb055    schedule 11.01.2019
comment
Нет, я имею в виду, что когда вы хотите показать диалоговое окно прогресса, должен быть ожидаемый метод, если нет ожидаемого метода, тогда вы не можете его показать.   -  person FreakyAli    schedule 11.01.2019
comment
@G.hakim Я жду ExecuteWithRetryAsync   -  person bigb055    schedule 11.01.2019
comment
Затем покажите диалоговое окно перед вызовом метода ExecuteWithRetryAsync   -  person FreakyAli    schedule 11.01.2019
comment
@G.hakim взгляните на обновление 2   -  person bigb055    schedule 11.01.2019
comment
Проверьте мой ответ   -  person FreakyAli    schedule 11.01.2019


Ответы (1)


Причина, по которой ваш прогресс не вращается, заключается в том, что он не является неопределенным, добавьте следующий код, и он должен работать

 progress.Indeterminate = true;

 progress.SetProgressStyle(Android.App.ProgressDialogStyle.Spinner);

Обновить

Поместите следующую строку

result = methodInfo?.Invoke(Utility.WsHueckmann, args) 

внутри await Task.Run, чтобы он стал

await Task.Run(() => { result = methodInfo?.Invoke(Utility.WsHueckmann, args); }) 

и теперь он работает, и счетчик обновляется.

person FreakyAli    schedule 11.01.2019
comment
Не помогло. Я думаю, проблема в том, что поток пользовательского интерфейса блокируется и не может обновить анимацию счетчика. Если я вставлю большую задержку, она будет вращаться некоторое время, а затем снова заблокируется. - person bigb055; 11.01.2019
comment
Вместо того, чтобы создавать новый диалог прогресса при каждом нажатии кнопки или что-то еще, почему бы вам просто не определить свой прогресс в методе OnCreate, а затем просто показать и отклонить в своих методах - person FreakyAli; 11.01.2019
comment
Потому что существует слишком много методов, вызывающих ExecuteWithRetryAsync, и слишком много усилий вручную оборачивать каждый отдельный вызов в show и reject. Как бы то ни было, я нашел решение, проверьте обновленное описание. - person bigb055; 11.01.2019
comment
Хорошо, если вы хотите, я могу обновить свой ответ, и вы можете отметить его как правильный? Было бы проще для тех, кто имеет тот же вопрос - person FreakyAli; 11.01.2019