无法从 ThrowIfCancellationRequested() 捕获异常
Can't catch exception from ThrowIfCancellationRequested()
好吧,我有这个代码:
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");
}
}
此时应用程序崩溃了,在调试时我发现 ThrowIfCancellationRequested()
抛出的异常未得到处理。
编辑:
好的,真的发生了一些奇怪的事情,我删除了第一个 if(ct.IsCancellationRequested) ct.ThrowIfCancellationRequested();
并听从了 Peter 的建议,lambda 中的 Throw 现在抛出异常,我放在它上面的 try catch 块也没有工作,但是 try catch在 lambda 之外捕获了异常。这是代码:
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");
}
}
它有点适合我:)
不过还是想了解一下这里是怎么回事
您正在传递 StartTimer
一个 lambda,它会在取消发生时抛出 CancellationException
,但此异常不一定会在 StartTimer
或 [=13= 的范围内触发].
我的猜测是,因为我不使用 Xamarin,所以计时器代码 运行 您的 lambda 在单独的任务上看到异常并将其升级为应用程序故障。
如果您在 lambda 中捕获 CancellationException
并且 return false 这应该具有停止计时器的预期效果 而不会 向 Xamarin 传播异常定时器代码。
请注意,直接调用 ct.ThrowIfCancellationRequested()
将 捕获在 TimedSync
中并命中您的捕获块。
好吧,我有这个代码:
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");
}
}
此时应用程序崩溃了,在调试时我发现 ThrowIfCancellationRequested()
抛出的异常未得到处理。
编辑:
好的,真的发生了一些奇怪的事情,我删除了第一个 if(ct.IsCancellationRequested) ct.ThrowIfCancellationRequested();
并听从了 Peter 的建议,lambda 中的 Throw 现在抛出异常,我放在它上面的 try catch 块也没有工作,但是 try catch在 lambda 之外捕获了异常。这是代码:
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");
}
}
它有点适合我:) 不过还是想了解一下这里是怎么回事
您正在传递 StartTimer
一个 lambda,它会在取消发生时抛出 CancellationException
,但此异常不一定会在 StartTimer
或 [=13= 的范围内触发].
我的猜测是,因为我不使用 Xamarin,所以计时器代码 运行 您的 lambda 在单独的任务上看到异常并将其升级为应用程序故障。
如果您在 lambda 中捕获 CancellationException
并且 return false 这应该具有停止计时器的预期效果 而不会 向 Xamarin 传播异常定时器代码。
请注意,直接调用 ct.ThrowIfCancellationRequested()
将 捕获在 TimedSync
中并命中您的捕获块。