针对C#5(在.net 4.5中)的fire and forget中的异常处理

针对C#5(在.net 4.5中)的fire and forget中的异常处理,c#,asynchronous,error-handling,task-parallel-library,.net-4.5,C#,Asynchronous,Error Handling,Task Parallel Library,.net 4.5,考虑以下“点燃并忘记”用例: 调用方从我的方法请求一些数据。我的方法检查缓存以查看数据是否已经存在。如果不是,它将从源中获取并缓存它。调用方不需要等待缓存发生后再获取结果,如果缓存发生故障,方法也不应该阻止调用方获取结果。我今天所拥有的是这样的: public Foo GetFoo(string fooKey) { // look for Foo with fooKey in cache // if Foo is not found, get Foo with fooKey fr

考虑以下“点燃并忘记”用例:

调用方从我的方法请求一些数据。我的方法检查缓存以查看数据是否已经存在。如果不是,它将从源中获取并缓存它。调用方不需要等待缓存发生后再获取结果,如果缓存发生故障,方法也不应该阻止调用方获取结果。我今天所拥有的是这样的:

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抛出一个异常,它将被忽略,并最终(在.NET4.5中)被框架吞噬。我宁愿自己最后一次清理异常,但我不想阻止当前线程。最好的方法是什么

这是我试过的

try
{
    ...
   cacheTask.ContinueWith
            (
                (e) => { 
                         if (cacheTask.IsFaulted) 
                            { 
                             /* log cacheTask.Exception */; 
                             } 
                        }
                , TaskContinuationOptions.OnlyOnFaulted
            ); 
}
有更好的办法吗?我是否需要IsFaulted上的“if”语句,还是因为我已经指定了“OnlyOnFaulted”而多余

任何意见/建议都将不胜感激。

四件事:

  • 不,你不需要这个;回调只有在出现故障时才会触发
  • 您不需要捕获
    cacheTask
    ;回调中的
    e
    是同一个任务,因此您不妨使用它。(这样,同一个委托可以用于所有任务。)
  • 如果您总是以相同的方式登录,那么您可能希望在任务上编写一个扩展方法,以便轻松地完成此任务
  • 作为添加处理程序的替代方案,可以考虑订阅和执行日志记录

哇。太快了。谢谢你,乔恩!我抓不住。在这方面.NET4.0和4.5有什么区别吗?那是什么呢?@Гааааааааааааааааааа。NET 4.0将在任务以未被观察的方式出现故障时终止整个进程。NET 4.5没有。@Гаааааааааааааааааааааааа107。如果一个人能将一项任务标记为fire and遗忘,那就太好了。因此,没有可能的等待/继续。由于在这种情况下没有人处理异常,它会使应用程序崩溃,因此您有一个很好的转储文件,可以在抛出异常的时间点查看本地变量和堆。。。