简体   繁体   中英

Exception handling in fire and forget for C# 5 (in .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;
}

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?

Here is what I've tried

try
{
    ...
   cacheTask.ContinueWith
            (
                (e) => { 
                         if (cacheTask.IsFaulted) 
                            { 
                             /* log cacheTask.Exception */; 
                             } 
                        }
                , TaskContinuationOptions.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.

Four things:

  • 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM