Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 910
Bill Sourour Avatar asked Apr 11 '13 15:04

Bill Sourour


People also ask

How do you handle exceptions in C?

Exception Handling Using try-catch block When that statement is executed an exception is generated, which is caught by the catch block. The object of the type IndexOutOfRangeException is used to display a message to the user about the exception that has occurred.

What is a fire and forget method?

Fire-and-forget is a type of missile guidance which does not require further external intervention after launch such as illumination of the target or wire guidance, and can hit its target without the launcher being in line-of-sight of the target.

What is exception handling in c3?

Exception Handling in C# is a process to handle runtime errors. We perform exception handling so that normal flow of the application can be maintained even after runtime errors. In C#, exception is an event or object which is thrown at runtime.

Is async void fire and forget?

A async void method is a “fire and forget” asynchronous operation. The caller can never wait for any result, and can't know when the operation completes or whether it was successful. You should use void when you know that no caller will ever need to know when the operation is finished or whether it succeeded.


1 Answers

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
like image 100
Jon Skeet Avatar answered Sep 27 '22 22:09

Jon Skeet