我试图理解为什么下面的代码:
async void Handle_Clicked(object sender, System.EventArgs e)
{
try
{
await CrashAsync("aaa");
}
catch (Exception exception)
{
Log($"observed exception");
Log($"Exception: {exception.Message}");
}
}
private async Task CrashAsync(string title)
{
Log($"CrashAsync ({title}) - before");
await Task.Delay(1000);
throw new Exception($"CrashAsync ({title})");
Log($"CrashAsync ({title}) - after");
}
产生预期结果:
线程 #1:CrashAsync (aaa) - 之前
线程#1:观察到的异常
线程 #1:异常:CrashAsync (aaa)
但如果我把它改成这个:
async void Handle_Clicked(object sender, System.EventArgs e)
{
try
{
await CrashAsync("aaa").ContinueWith(async (t) =>
{
await CrashAsync("bbb");
},TaskContinuationOptions.OnlyOnRanToCompletion);
}
catch (Exception exception)
{
Log($"observed exception");
Log($"Exception: {exception.Message}");
}
}
我得到以下输出:
线程 #1:CrashAsync (aaa) - 之前
线程#1:观察到的异常
线程#1:异常:任务被取消。
线程#2:未观察到的异常
线程#2:System.Exception:CrashAsync(aaa)
在 /Users/johndoe/Development/Xamarin/AsyncTest/AsyncTest/AsyncTestPage.xaml.cs:82 中的 AsyncTest.AsyncTestPage+c__async3.MoveNext () [0x000ad]
where:
TaskScheduler.UnobservedTaskException += (sender, e) =>
{
Debug.WriteLine($"thread #{Environment.CurrentManagedThreadId}: unobserved exception");
foreach (var exception in e.Exception.Flatten().InnerExceptions)
{
Debug.WriteLine($"thread #{Environment.CurrentManagedThreadId}: {exception}");
}
};
不满足继续条件,因此ContinueWith任务被取消,但为什么会出现未观察到的异常?
你等待着Task
由返回ContinueWith
,所以你观察到与此相关的异常Task
- 它被取消了(TaskCanceledException
)。但是您没有观察到 CrashAsync 抛出的原始异常(因此“CrashAsync aaa”)异常,因此您观察到的行为。
以下是示例代码,可以帮助您更好地理解:
static async void Test() {
var originalTask = CrashAsync("aaa");
var onSuccess = originalTask.ContinueWith(async (t) =>
{
await CrashAsync("bbb");
}, TaskContinuationOptions.OnlyOnRanToCompletion);
var onFault = originalTask.ContinueWith(t => {
Log("Observed original exception: " + t.Exception.InnerExceptions[0].Message);
}, TaskContinuationOptions.OnlyOnFaulted);
}
简而言之 - 只需等待您的任务并捕获异常(如果有)。你不需要使用ContinueWith
根本没有,因为如果你使用await - 该方法的其余部分是already一个延续。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)