简体   繁体   English

无法从ThrowIfCancellationRequested()中捕获异常

[英]Can't catch exception from ThrowIfCancellationRequested()

Welp, I've this code: 威尔,我有这段代码:

    public static async Task TimedSync (CancellationToken ct)
    {
        try {
            if (ct.IsCancellationRequested)
                ct.ThrowIfCancellationRequested();
            await Task.Run(async () => await UP.Sincronizacao.SyncDB(true));
            Xamarin.Forms.Device.StartTimer(TimeSpan.FromMinutes(1), () => {
                if (ct.IsCancellationRequested)
                    ct.ThrowIfCancellationRequested();
                Task.Run(async () => await UP.Sincronizacao.SyncDB(false));
                return true;
            });
        } catch (OperationCanceledException) {
            await Current.MainPage.DisplayAlert("Got it", "Good", "ok");
        } catch (Exception e) {
            await Current.MainPage.DisplayAlert("Oops", e.Message, "dismiss");
        }
    }

The app just crashes at this point, and on debug I find that the exception thrown by ThrowIfCancellationRequested() is unhandled. 该应用程序此时已崩溃,在调试时,我发现ThrowIfCancellationRequested()引发的异常ThrowIfCancellationRequested()得到处理。

Edit: Ok, something really weird happened, I removed the first if(ct.IsCancellationRequested) ct.ThrowIfCancellationRequested(); 编辑:好的,确实发生了一些奇怪的事情,我删除了第一个if(ct.IsCancellationRequested) ct.ThrowIfCancellationRequested(); and followed Peter's suggestion, the Throw inside the lambda now throws the exception, the try catch block I put on it as well didn't work, but the try catch outside the lambda caught the exception. 并按照彼得的建议,在lambda内的Throw现在引发了异常,我也放在它上面的try catch块没有用,但是在lambda之外的try catch捕获了异常。 Here's the code: 这是代码:

    public static async Task TimedSync (CancellationToken ct)
    {
        try {
            await Task.Run(async () => await UP.Sincronizacao.SyncDB(true));
            Xamarin.Forms.Device.StartTimer(TimeSpan.FromMinutes(1), () => {
                try {
                    if (ct.IsCancellationRequested)
                        ct.ThrowIfCancellationRequested();
                    Task.Run(async () => await UP.Sincronizacao.SyncDB(false));
                    return true;
                } catch (OperationCanceledException) {
                    return false;
                }
            });
        } catch (OperationCanceledException) {
            await Current.MainPage.DisplayAlert("Got it", "Good", "ok");
        } catch (Exception e) {
            await Current.MainPage.DisplayAlert("Oops", e.Message, "dismiss");
        }
    }

It kinda works for me :) But still would like to understand what's going on here 有点对我有用:)但仍然想了解这里发生了什么

You are passing StartTimer a lambda that will throw a CancellationException when cancellation happens, but this exception doesn't necessarily fire inside StartTimer or the scope of TimedSync . 您正在传递给StartTimer一个lambda值,当取消发生时它将抛出CancellationException ,但是不一定会在StartTimerTimedSync范围内触发此异常。

My guess, because I don't use Xamarin, is that the timer code running your lambda sees the exception on a separate task and promotes that to an application failure. 我的猜测是因为我不使用Xamarin,所以运行您的lambda的计时器代码会在单独的任务上看到异常并将其提升为应用程序故障。

If you catch CancellationException in the lambda and return false this should have the desired effect of stopping the timer without propagating an exception to the Xamarin timer code. 如果您在lambda中捕获CancellationException并返回false,则这应具有停止计时器而不将Xamarin计时器代码传播异常的预期效果。

Note that the direct call to ct.ThrowIfCancellationRequested() will be caught inside TimedSync and hit your catch block. 请注意,对ct.ThrowIfCancellationRequested()的直接调用TimedSync捕获并点击您的catch块。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM