异常处理引发火灾,而忘记了C#5(在.net 4.5中) [英] Exception handling in fire and forget for C# 5 (in .net 4.5)

查看:92
本文介绍了异常处理引发火灾,而忘记了C#5(在.net 4.5中)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下一劳永逸"用例:

Consider the following "fire-and-forget" use case:

调用者从我的方法中请求一些数据.我的方法检查缓存以查看数据是否已经存在.如果不是,它将从源获取并缓存它.调用者在获取结果之前不必等待缓存发生,并且如果缓存发生故障,该方法也不应阻止调用者获得结果.我今天所拥有的看起来像这样:

A caller requests some data from my method. My method checks the cache to see if the data is already there. If it's not, it fetches it from the source and caches it. The caller shouldn't need to wait for the caching to occur before getting his results and the method shouldn't prevent the caller from getting a result if the caching happens to fail. What I have today, looks like this:

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中)被框架吞噬.我宁愿自己清理异常,但也不想阻塞当前线程.最好的方法是什么?

If CacheFoo throws an Exception it goes unobserved and eventually (in .Net 4.5) it gets swallowed up by the framework. I'd rather have a last shot at cleaning up the exception myself, but I don't want to block the current thread. What's the best way to do that?

这是我尝试过的

try
{
    ...
   cacheTask.ContinueWith
            (
                (e) => { 
                         if (cacheTask.IsFaulted) 
                            { 
                             /* log cacheTask.Exception */; 
                             } 
                        }
                , TaskContinuationOptions.OnlyOnFaulted
            ); 
}

有更好的方法吗?我是否需要在IsFaulted上使用"if"语句,还是因为我已经指定了"OnlyOnFaulted"而多余了?

Is there a better way? Do I need the "if" statement on IsFaulted or is that redundant because I've already specified "OnlyOnFaulted"?

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

Any opinions/suggestions would be much appreciated.

推荐答案

四件事:

  • No, you don't need the Task.IsFaulted property; the callback will only fire if it's faulted
  • You don't need to capture cacheTask; the e in your callback is the same task, so you might as well use that instead. (Then the same delegate can be used for all tasks.)
  • If you're always logging in the same way, you may want to write an extension method on task to make it easy to do this
  • As an alternative to adding a handler, you could consider subscribing to TaskScheduler.UnobservedTaskException and performing logging there

这篇关于异常处理引发火灾,而忘记了C#5(在.net 4.5中)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆