Xamarin.Forms.NavigationProxy.PopAsync:System.ArgumentOutOfRangeException:索引超出范围

时间:2016-12-06 12:20:52

标签: xamarin.ios xamarin.forms

我最近在iOS上的Xamarin应用程序中遇到了这个奇怪的例外。我目前很难在HockeyApp中正确地表示它,但无论如何这里是来自HA的崩溃记者日志:

Hardware Model:      iPhone4,1
Process:         trucker_rolspedi [625]
Path:            /var/containers/Bundle/Application/B028371C-62B4-4BCD-8491-C78EFE825D22/trucker_rolspediOS.app/trucker_rolspediOS
Identifier:      com.rolsped.TruckerApp
Version:         1.1 (60)
Code Type:       ARM
Parent Process:  ??? [1]

Date/Time:       2016-12-04T04:53:09Z
Launch Time:     2016-12-04T04:46:07Z
OS Version:      iPhone OS 9.3.5 (13G36)
Report Version:  104-Xamarin

Exception Type:  SIGABRT
Exception Codes: #0 at 0x21efec5c
Crashed Thread:  0

Application Specific Information:
*** Terminating app due to uncaught exception 'System.ArgumentOutOfRangeException', reason: 'System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.'

Xamarin Exception Stack:
Parameter name: index
  at System.ThrowHelper.ThrowArgumentOutOfRangeException (System.ExceptionArgument argument, System.ExceptionResource resource) <0x384df0 + 0x00040> in <15e850188d9f425bbeae90f0bbc51e17#ddbdd0f52c53581cb2d9c691bfe34183>:0 
  at System.ThrowHelper.ThrowArgumentOutOfRangeException () <0x384b68 + 0x0001b> in <15e850188d9f425bbeae90f0bbc51e17#ddbdd0f52c53581cb2d9c691bfe34183>:0 
  at System.Collections.Generic.List`1[T].get_Item (System.Int32 index) <0x24a68c + 0x0002f> in <15e850188d9f425bbeae90f0bbc51e17#ddbdd0f52c53581cb2d9c691bfe34183>:0 
  at Xamarin.Forms.NavigationProxy.Pop () <0x5678b4 + 0x00047> in <f9095492ed2b43559d0236ac22ab7223#ddbdd0f52c53581cb2d9c691bfe34183>:0 
  at Xamarin.Forms.NavigationProxy.OnPopAsync (System.Boolean animated) <0x567518 + 0x0005b> in <f9095492ed2b43559d0236ac22ab7223#ddbdd0f52c53581cb2d9c691bfe34183>:0 
  at Xamarin.Forms.NavigationProxy.PopAsync (System.Boolean animated) <0x56708c + 0x0002f> in <f9095492ed2b43559d0236ac22ab7223#ddbdd0f52c53581cb2d9c691bfe34183>:0 
  at trucker_rolsped.Pages.Media.TaskPhotoUploadPage+<SendMediaOnClicked>d__9.MoveNext () <0xe86944 + 0x013bf> in <3fbc044b4d76429b8dee1ec91e769c22#ddbdd0f52c53581cb2d9c691bfe34183>:0 

这里的代码来自根本原因Stacktrace行。它必须发生在await Navigation.PopAsync(animated: false)声明:

       private async void SendMediaOnClicked(object sender, EventArgs e)
        {
            SendMedia.IsEnabled = false;

            try
            {
                SelectedMedia.DokArt = _dokArt;
                SelectedMedia.TruckAppId = _truckAppId;

                UserDialogs.Instance.ShowLoading("Foto wird hochgeladen...");

                await AzureBlobStorageManager.Instance.UploadMediaAsync(SelectedMedia);

                UserDialogs.Instance.HideLoading();

                switch (SelectedMedia.MediaState)
                {
                    case MediaState.Uploaded:

                        if (IsTakenPhoto)
                        {
                            var result = await DisplayAlert("Foto Upload", "Foto wurde erfolgreich hochgeladen. Möchten Sie das Foto jetzt vom Handy löschen?", "Ja", "Nein");

                            if (result)
                            {
                                //Platform specific file delete
                                var truckerappMedia = SelectedMedia.File.Path;

                                var platformFileHandler = DependencyService.Get<IFileHandling>();

                                if (platformFileHandler != null)
                                    if (await platformFileHandler.FileExistsAsync(truckerappMedia))
                                    {
                                        var deleted = await platformFileHandler.DeleteFileAsync(truckerappMedia);

                                        if (deleted)
                                            UserDialogs.Instance.Toast("Foto wurde erfolgreich hochgeladen und am Handy gelöscht!!", TimeSpan.FromSeconds(value: 2));

                                        else
                                            UserDialogs.Instance.Toast("Foto konnte nicht gelöscht werden! Falls Sie das Foto nicht benötigen " +
                                                                               "bitte in der Fotogallery selbst löschen", TimeSpan.FromSeconds(value: 5));

                                    }
                            }
                        }
                        else
                            UserDialogs.Instance.Toast("Upload erfolgreich!", TimeSpan.FromSeconds(value: 2));


                        break;
                    case MediaState.Queued:
                        UserDialogs.Instance.Toast("Upload erfolgt automatisch wenn Sie wieder mit Internet oder dem mobilem Netz verbunden sind!");
                        break;
                    case MediaState.Created:
                        await DisplayAlert("Media Info", "Upload MediaState.Created!", "Ok");
                        break;
                    case MediaState.Error:
                        await DisplayAlert("Media Info", "Upload MediaState.Error!", "Ok");
                        break;
                    default:
                        await DisplayAlert("Media Info", "Upload MediaState Unknown!", "Ok");
                        break;
                }
            }
            catch (Exception ex)
            {
                SelectedMedia.MediaState = MediaState.Error;
                await DisplayAlert("Sende Media Fehler", ex.Message, "Ok");
            }
            finally
            {
                if (SelectedMedia.MediaState == MediaState.Uploaded)
                {
                    SelectedMedia?.Dispose();
                    SelectedMedia = null;
                }

                _workflowItem.TruckAuftragWorkFlow.TaskStatusId = 80;

                await Navigation.PopAsync(animated: false);
                _tcs.SetResult(true);
            }
        }

这里是我实例化并使用TakePhotoUploadPage的2个代码区域:

1。用法:来自另一个名为Task40ActionPage的页面

在** Task40ActionPage **我调用该方法来显示TakePhotoUploadPage:

private async void RejectLoadInTimeClicked(object sender, EventArgs e)
{
    _workflowItem.TruckAuftragLauf.FlagFotoLadezeit = null;

    try
    {
        await ShowPhotoPageAsync(this, _workflowItem);
    }
    catch (Exception ex)
    {
        await MetricsManagerHelper.Instance.SendExceptionToApplicationInsights(ex);
    }

    await Navigation.PopAsync(animated: false);
    _tcs.SetResult(true);
}

public async Task<bool> ShowPhotoPageAsync(Page page, WorkflowItem workflowItem)
{
    TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();

    try
    {
        await Navigation.PushAsync(new TaskPhotoUploadPage(tcs, workflowItem, dokArt: "50"), animated: false);
    }
    catch (Exception e)
    {
        tcs.SetException(e);
    }

    return await tcs.Task;
}

2。用法:来自ICommand Action委托:

    public async Task Task50ActionAsync(WorkflowItem workflowItem)
    {
        bool isLastWorkItem = false;
        var page = Application.Current.MainPage.Navigation.NavigationStack.LastOrDefault();

        try
        {
            if (workflowItem.QuestionYn)
            {
                if (page != null)
                    Device.BeginInvokeOnMainThread(
                        async () =>
                        {
                            try
                            {
                                bool isOk = await page.DisplayAlert("Todo Command", "Task50ActionAsync ausführen?", "Ja", "Nein");

                                if (isOk)
                                {
                                    await ShowPhotoPageAsync(page, workflowItem, dokArt: "60");

                                    UserDialogs.Instance.ShowLoading("Aufgabe wird gespeichert...", MaskType.Black);
                                    isLastWorkItem = await InnerTask50ActionAsync(workflowItem);

                                    //PUSH changes to remote.db
                                    await OfflineSyncStoreManager.Instance.PushAsync(OfflineSyncStoreManager.Instance.TruckAuftragWorkFlowTable.TableName);

                                    if (isLastWorkItem)
                                    {
                                        // Set TAL to completed
                                        workflowItem.TruckAuftragLauf.IsCompleted = true;

                                        // Pop Workflow UI View
                                        Device.BeginInvokeOnMainThread(async () => await page.Navigation.PopAsync(animated: false));
                                    }
                                    UserDialogs.Instance.HideLoading();
                                }
                            }
                            catch (Exception e)
                            {
                                await MetricsManagerHelper.Instance.SendExceptionToApplicationInsights(e);

                                Device.BeginInvokeOnMainThread(
                                    async () =>
                                    {
                                        await
                                            page.DisplayAlert("Todo Command Error",
                                                $"TaskId={workflowItem.TaskId} Action Error:{e}", "Ok");
                                    });
                            }
                        });
            }
            else
            {
                await ShowPhotoPageAsync(page, workflowItem, dokArt: "60");

                UserDialogs.Instance.ShowLoading("Aufgabe wird gespeichert...", MaskType.Black);
                isLastWorkItem = await InnerTask50ActionAsync(workflowItem);

                //PUSH changes to remote.db
                await OfflineSyncStoreManager.Instance.PushAsync(OfflineSyncStoreManager.Instance.TruckAuftragWorkFlowTable.TableName);

                if (isLastWorkItem)
                {
                    // Set TAL to completed
                    workflowItem.TruckAuftragLauf.IsCompleted = true;

                    // Pop Workflow UI View
                    Device.BeginInvokeOnMainThread(async () => await page.Navigation.PopAsync(animated: false));
                }
                UserDialogs.Instance.HideLoading();
            }
        }
        catch (Exception e)
        {
            await MetricsManagerHelper.Instance.SendExceptionToApplicationInsights(e);

            if (page != null)
                Device.BeginInvokeOnMainThread(
                    async () =>
                    {
                        await
                            page.DisplayAlert("Todo Command Error", $"TaskId={workflowItem.TaskId} Action Error:{e}",
                                "Ok");
                    });
        }
    }

    public async Task<bool> ShowPhotoPageAsync(Page page, WorkflowItem workflowItem, string dokArt)
    {
        TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();

        try
        {
            await page.Navigation.PushAsync(new TaskPhotoUploadPage(tcs, workflowItem, dokArt: dokArt), animated: false);
        }
        catch (Exception e)
        {
            tcs.SetException(e);
        }

        return await tcs.Task;
    }

感谢所有人提前提供有用的建议,

埃里克

1 个答案:

答案 0 :(得分:1)

作为Yuri S。建议当Stack为空时,代码可以修复NavigationStack PopAsync:

                if (Navigation.NavigationStack.Count == 1)
            {
                await MetricsManagerHelper.Instance.SendErrorToApplicationInsightsAsync($"Navigationstack Count == 1");
            }
            else
            {
                await Navigation.PopAsync(animated: false);
            }

感谢您的大力支持!!!

埃里克