假设您有 2 个 async
方法定义如下:
public async Task<TResult> SomeMethod1()
{
throw new Exception();
}
public async Task<TResult> SomeMethod2()
{
await Task.Delay(50);
throw new Exception();
}
现在,如果您在这 2 个方法上await
,行为将几乎相同。但是,如果您正在执行任务,则行为会有所不同。
如果我想缓存这种计算的结果,但仅当任务运行完成时才缓存。 我必须处理两种情况:
第一种情况:
public Task<TResult> CachingThis1(Func<Task<TResult>> doSomthing1)
{
try
{
var futur = doSomthing1()
futur.ContinueWith(
t =>
{
// ... Add To my cache
},
TaskContinuationOptions.NotOnFaulted);
}
catch ()
{
// ... Remove from the pending cache
throw;
}
}
第二种情况
public Task<TResult> CachingThis2(Func<Task<TResult>> doSomthing)
{
var futur = SomeMethod2();
futur.ContinueWith(
t =>
{
// ... Add To my cache
},
TaskContinuationOptions.NotOnFaulted);
futur.ContinueWith(
t =>
{
// ... Remove from the pending cache
},
TaskContinuationOptions.OnlyOnFaulted);
}
现在我将执行缓存计算的方法传递给我的缓存系统。
cachingSystem.CachingThis1(SomeMethod1);
cachingSystem.CachingThis2(SomeMethod2);
很明显,我需要在“ConinueWith
on faulted”和 catch block 中复制代码。
您知道是否有办法使异常在等待之前或之后表现相同?
最佳答案
SomeMethod1
和 SomeMethod2
所需的异常处理没有区别。它们的运行方式完全相同,异常将存储在返回的任务中。
这在这个例子中很容易看出;
static void Main(string[] args)
{
try
{
var task = SomeMethod1();
}
catch
{
// Unreachable code
}
}
public static async Task SomeMethod1()
{
throw new Exception();
}
在这种情况下不会处理任何异常,因为没有等待返回的任务。
然而,简单的 Task
返回方法和 async
方法之间存在区别:
public static Task TaskReturning()
{
throw new Exception();
return Task.Delay(1000);
}
public static async Task Async()
{
throw new Exception();
await Task.Delay(1000);
}
您可以通过简单地使用 async
包装器方法来避免代码重复,该方法既调用该方法又在单个 try-catch< 中
block :等待
返回的任务
public static async Task HandleAsync()
{
try
{
await TaskReturning();
// Add to cache.
}
catch
{
// handle exception from both the synchronous and asynchronous parts.
}
}
关于c# - 异步方法异常的不同行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27106532/