简体   繁体   中英

How to create pass through Task.ContinueWith?

I want to tack on a task at the end of an original task, but would like to preserve the original result and type. The appended task is just for logging purpose, such as writing to console, etc. For example:

Task.Run(() => DateTime.Now.Hour > 12 ? "Hey!" : throw new Exception())
    .ContinueWith(t =>
    {
        if (t.IsCompletedSuccessfully)
        {
            Console.WriteLine("Success");
            return t.Result;
        }
        else
        {
            Console.WriteLine("Failure");
            throw t.Exception;
        }
    });

The type of the original task is Task<string> . Here I return t.Result if the task doesn't encounter error, and I throw t.Exception in case the task encounters error. Looks like the type remains Task<string> but not sure about the exception side.

Is this the right way to do it? Or is there a better way?

There is no reason to rethrow the exception. The task will throw AggregrateException and you can get the real exceptions with InnerExceptions property to handle them.

For logging, you can separate success and failure using TaskContinuationOptions :

var t = Task.Run(() => DateTime.Now.Hour > 12 ? "Hey!" : throw new Exception());

t.ContinueWith(_ => Console.WriteLine("Success"), TaskContinuationOptions.OnlyOnRanToCompletion);

t.ContinueWith(_ => Console.WriteLine("Faiure"), TaskContinuationOptions.OnlyOnFaulted);

The success will be logged only if task executed successfully until the end. And failure will be logged if there was an unhandled exception.

This separates logging and getting the result. So you can just get the result from the first task.

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