0

I have async method ExecuteWithRetryAsync which implements some retry logic and must show ProgressDialog as soon as it is called. Currently the first call to Show() never really works. The progress dialog shows only after the AlertDialog is confirmed (second comment). How do I make Show() at the beginning of ExecuteWithRetryAsync actually show the progress dialog?

  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);
}
}

UPDATE: I observed that when connection of device is disabled it takes about ~10-15 secs for ExecuteWithRetryAsync to start execution and in the meantime device shows app not responding dialog several times, whereas with the connection on it executes immediately. Why that?

UPDATE 2: When I put await Task.Delay (50) after calling Show() it does show, but the progress dialog animation is not updating, it's frozen.

UPDATE 3: I put following line result = methodInfo?.Invoke(Utility.WsHueckmann, args) inside await Task.Run so it becomes await Task.Run(() => { result = methodInfo?.Invoke(Utility.WsHueckmann, args); }) and now it's working and spinner is updating.

bigb055
  • 198
  • 3
  • 14

1 Answers1

1

The reason behind your progress not spinning is because it is not indeterminate add the following code and it should work

 progress.Indeterminate = true;

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

Update

Put the following line

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

inside await Task.Run so it becomes

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

and now it's working and spinner is updating.

FreakyAli
  • 13,349
  • 3
  • 23
  • 63
  • Did not help. I think the problem is UI Thread is getting blocked and cannot update the spinner animation. If I insert bigger Delay it would spin for some time and then block again. – bigb055 Jan 11 '19 at 16:20
  • Rather than creating a new progress dialog on every button click or whatever even that is why don't you just define your progress in OnCreate method and then just show and dismiss in your methods – FreakyAli Jan 11 '19 at 16:26
  • Because there are too many methods calling `ExecuteWithRetryAsync` and it's too much effort to manually wrap every single call with show and dismiss. Whatever, I found a solution, check updated description. – bigb055 Jan 11 '19 at 16:41
  • Well if you want i can update my answer and you can mark it as correct? Would be easier for someone who has the same question – FreakyAli Jan 11 '19 at 16:44