Xamarin.Forms PopModalAsync:未观察到Task的异常

时间:2019-08-23 09:34:40

标签: c# xamarin xamarin.forms

我有以下代码:

System.Threading.Tasks.Task appointmentEndTask = App.ArdaBusinessLogic.AppointmentEnd(_appointment);
System.Threading.Tasks.Task appointmentEndCompletedTask = appointmentEndTask.ContinueWith(
    async task =>
    {
        _appointmentDetailPage.IsDirty = true;
        await App.MasterNavigationPage.Navigation.PopModalAsync();
    }, 
    System.Threading.CancellationToken.None, 
    System.Threading.Tasks.TaskContinuationOptions.OnlyOnRanToCompletion, 
    System.Threading.Tasks.TaskScheduler.FromCurrentSynchronizationContext());

System.Threading.Tasks.Task appointmentEndFaultedTask = appointmentEndTask.ContinueWith(
    async task =>
    {
        await App.MasterNavigationPage.Navigation.PopModalAsync();
        await App.ShowErrorPageAsync(task.Exception);
    }, 
    System.Threading.CancellationToken.None, 
    System.Threading.Tasks.TaskContinuationOptions.OnlyOnFaulted, 
    System.Threading.Tasks.TaskScheduler.FromCurrentSynchronizationContext());

因此,如果“ AppointmentEnd”任务完成,则应关闭当前的模态页面。有时(并非总是如此!),我的崩溃日志中出现以下错误。在这种情况下,行号139是“ _appointmentDetailPage.IsDirty = true”之后的“ await App.MasterNavigationPage.Navigation.PopModalAsync()”。

Xamarin caused by: android.runtime.JavaProxyThrowable:
System.AggregateException: A Task's exception(s) were not observed
either by Waiting on the Task or accessing its Exception property. As
a result, the unobserved exception was rethrown by the finalizer
thread. ---System.ArgumentOutOfRangeException: Index was out of
range. Must be non-negative and less than the size of the collection.
Parameter name: index   at
System.Collections.Generic.List`1[T].get_Item (System.Int32 index)
[0x00009] in
/Users/builder/jenkins/workspace/xamarin-android-d15-9/xamarin-android/external/mono/external/corefx/src/Common/src/CoreLib/System/Collections/Generic/List.cs:180
at Xamarin.Forms.Application+NavigationImpl+<OnPopModal>d__2.MoveNext
() [0x00022] in D:\a\1\s\Xamarin.Forms.Core\Application.cs:381
--- End of stack trace from previous location where exception was thrown ---   at
CPM.Arda.Mobile.Freelancer.Ui.Pages.Appointment.Complete+<<confirmButton_Clicked>b__5_0>d.MoveNext
() [0x0007d] in
D:\ProjekteTFVC\ArdaMobileFreelancer\SourceCode\Ui\1.0\Pages\Appointment\Complete.xaml.cs:139
--- End of inner exception stack trace ---
---(Inner Exception #0) System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the
collection. Parameter name: index   at
System.Collections.Generic.List`1[T].get_Item (System.Int32 index)
[0x00009] in
/Users/builder/jenkins/workspace/xamarin-android-d15-9/xamarin-android/external/mono/external/corefx/src/Common/src/CoreLib/System/Collections/Generic/List.cs:180
at Xamarin.Forms.Application+NavigationImpl+<OnPopModal>d__2.MoveNext
() [0x00022] in D:\a\1\s\Xamarin.Forms.Core\Application.cs:381
--- End of stack trace from previous location where exception was thrown ---   at
CPM.Arda.Mobile.Freelancer.Ui.Pages.Appointment.Complete+<<confirmButton_Clicked>b__5_0>d.MoveNext
() [0x0007d] in
D:\ProjekteTFVC\ArdaMobileFreelancer\SourceCode\Ui\1.0\Pages\Appointment\Complete.xaml.cs:139

不幸的是,我不明白如何导致此错误。你能帮我吗?

1 个答案:

答案 0 :(得分:1)

首先,为什么要使用这么复杂的语法而不是利用异步等待?

public async void EndAppointement()
{
    try 
    {
        await App.ArdaBusinessLogic.AppointmentEnd(_appointment);
        _appointmentDetailPage.IsDirty = true;
        await App.MasterNavigationPage.Navigation.PopModalAsync();
    }
    catch (Exception exception)
    {
        await App.MasterNavigationPage.Navigation.PopModalAsync();
        await App.ShowErrorPageAsync(exception);
    }
}

第二,查看XF源代码:

protected override async Task<Page> OnPopModal(bool animated)
{
    Page modal = ModalStack[ModalStack.Count - 1];
    if (_owner.OnModalPopping(modal))
    {
        _owner.OnPopCanceled();
        return null;
    }
    Page result = await base.OnPopModal(animated);
    result.Parent = null;
    _owner.OnModalPopped(result);
    return result;
}

您的模式堆栈似乎被弄乱了:这意味着您试图弹出不在堆栈上的页面。确定要进入模式页面吗?也许使用PopAsync代替PopModalAsync