考虑以下“即发即弃”用例:
调用者从我的方法请求一些数据。我的方法检查缓存以查看数据是否已经存在。如果不是,它会从源中获取它并缓存它。调用者在获取结果之前不需要等待缓存发生,并且如果缓存碰巧失败,该方法不应阻止调用者获取结果。我今天拥有的是这样的:
public Foo GetFoo(string fooKey)
{
// look for Foo with fooKey in cache
// if Foo is not found, get Foo with fooKey from source
// and assign it to local variable myFoo
Task cacheTask
= Task.Run
(
() => CacheFoo(myFoo)// fire-and-forget the caching of myFoo
);
return myFoo;
}
如果 CacheFoo 抛出一个异常,它就不会被观察到,最终(在 .Net 4.5 中)它会被框架吞没。我宁愿自己最后一次清理异常,但我不想阻塞当前线程。最好的方法是什么?
这是我试过的
try
{
...
cacheTask.ContinueWith
(
(e) => {
if (cacheTask.IsFaulted)
{
/* log cacheTask.Exception */;
}
}
, TaskContinuationOptions.OnlyOnFaulted
);
}
有没有更好的方法?我是否需要 IsFaulted 上的“if”语句,或者因为我已经指定了“OnlyOnFaulted”,所以它是多余的吗?
如有任何意见/建议,我们将不胜感激。
最佳答案
四件事:
- 不,你不需要 Task.IsFaulted property ;回调只会在出现故障时触发
- 你不需要捕获
cacheTask
;回调中的e
是相同的任务,因此您不妨改用它。 (然后同一个委托(delegate)可以用于所有任务。) - 如果您总是以相同的方式登录,您可能需要在任务上编写一个扩展方法,以便于执行此操作
- 作为添加处理程序的替代方法,您可以考虑订阅 TaskScheduler.UnobservedTaskException并在那里进行日志记录
关于c# - C# 5 中的异常处理(在 .net 4.5 中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15953520/