火灾中的异常处理和忘记C#5(在.net 4.5中)

时间:2013-04-11 15:59:35

标签: 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 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
            ); 
}

有更好的方法吗?我需要" if"关于IsFaulted的陈述还是多余的,因为我已经指定了" OnlyOnFaulted"?

非常感谢任何意见/建议。

1 个答案:

答案 0 :(得分:10)

四件事:

  • 不,你不需要Task.IsFaulted property;只有在出现故障时才会触发回调
  • 您无需捕获cacheTask;你的回调中的e是同一个任务,所以你也可以改用它。 (然后,同一个代理可以用于所有任务。)
  • 如果您总是以相同的方式登录,您可能希望在任务上编写扩展方法以便于执行此操作
  • 作为添加处理程序的替代方法,您可以考虑订阅TaskScheduler.UnobservedTaskException并执行日志记录