DEV Community

DEV Community

Serhii Korol

Posted on Jun 7, 2023

How to handle Task result in a more elegant way.

I'm sure many developers use the "async/await" methods in their work. And sure, there is needed to handle errors. I'll explain with examples how to do it in the right way. And above all, let's create a simple console application:

As you can see, I call async HTTP request, and for this article, it'll return an error with a 403 code. As a rule, the code in this way nobody writes because you'll get an exception, and the application will be stopped. Usually, such calls wrap in try…catch block. And if you create a lot of similar methods, you should add to each method this block. I'm getting that this work makes Copilot, but, produces a lot of repeatable code. This code will work, but it's bad practice:

I want to improve this code and make it more elegant and better. First of all, let's create our own result object that will keep results and errors. I created non-generic and generic classes.

Next step, let's create a helper to handle the Task. There are also two versions of handlers - non-generic and generic.

Let's check this out and rewrite our method:

And also make minor changes to the Main method:

Finally, you'll retrieve the same result as with the previous code, but without the try…catch block that you create only once. You can also add your favorite logger, but you need to make some changes in the code:

As you can see, this code is more readable and cleaner. Also, you can change the Result class as you need.

As a bonus, I want to show how to handle void methods if you don't need callbacks. However, in the void methods also can be exceptions and you should handle it. Let's return to the Helper class and add another method. In this method, I get ILogger which handles exceptions.

We need to install the package and register it to use this extension. Let's add this code:

And also it requires making a few changes to this method:

As you can see, I invoke the logger into the TryAwait method. When there throws an exception, the logger shows your message. Sure, you can change it for your needing.

That's all. I hope for someone it'll be useful. Happy coding!

Buy Me A Beer

Top comments (2)

pic

Templates let you quickly answer FAQs or store snippets for re-use.

pauljlucas profile image

  • Email [email protected]
  • Location San Francisco Bay Area
  • Education M.S., University of Illinois at Urbana-Champaign
  • Work Retired Principal Software Engineer
  • Joined Jan 21, 2017

This is mis-tagged. #c is the tag for C. You want #csharp .

serhii_korol_ab7776c50dba profile image

  • Work Software Engineer
  • Joined May 28, 2022

Thanks. Fixed.

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink .

Hide child comments as well

For further actions, you may consider blocking this person and/or reporting abuse

aivantuquero profile image

Beyond the Basics: Mastering JavaScript Closures for Powerful Code

Aivan Carlos Tuquero - Mar 26

isabeliita90 profile image

Upload a file to S3 with AWS Kotlin SDK

Isabel Garrido - Mar 14

wangliwen profile image

How many variations can be produced by obfuscating a single line of JavaScript code: 'var a=1'?

WangLiwen - Mar 14

codelink profile image

How to generate functioning NextJS apps from multiple images with AI?

CodeLink - Mar 26

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Dot Net Tutorials

How to Control the Result of a Task in C#

Back to: C#.NET Tutorials For Beginners and Professionals

How to Control the Result of a Task in C# using TaskCompletionSource

In this article, I am going to discuss How to Control the Result of a Task in C# using TaskCompletionSource with Examples. Please read our previous article where we discussed Only One Pattern in C# Asynchronous Programming with Examples.

How to Control the Result of a Task in C#?

So far, we have worked with tasks, and task status depends on an event. For example, if we make an HTTP request or if we make an Async method call, then the status of the task is associated with what happens with the HTTP Request or with the Async Method call, whether it is successful, or there is an exception or the operation is canceled using a cancellation token. With TaskCompletionSource , we can create a task for which we are the ones who will control its status, whether it is successful, canceled, or if it’s thrown an exception.

Constructors, Methods, and Properties of TaskCompletionSource class in C#:

If you go to the definition of TaskCompletionSource class in C#, you will see the following. You can see it is a generic class.

Constructors, Methods, and Properties of TaskCompletionSource class in C#

Constructors of TaskCompletionSource class:

The TaskCompletionSource class in C# provides the following 4 constructors that we can use to create an instance of the TaskCompletionSource class.

  • TaskCompletionSource(): It creates a System.Threading.Tasks.TaskCompletionSource object.
  • TaskCompletionSource(TaskCreationOptions creationOptions): It creates a TaskCompletionSource with the specified options. Here, the parameter creationOptions specify the options to use when creating the underlying Task.
  • TaskCompletionSource(object state): It creates a TaskCompletionSource with the specified state. Here, the parameter state specifies the state to use as the underlying Task’s AsyncState.
  • TaskCompletionSource(object state, TaskCreationOptions creationOptions): It creates a TaskCompletionSource with the specified state and options. Here, the parameter state specifies the state to use as the underlying Task’s AsyncState and the parameter creationOptions specify the options to use when creating the underlying Task.

Property of TaskCompletionSource class in C#:

The TaskCompletionSource class in C# provides the following property.

  • Task<TResult> Task { get; } : It returns the System.Threading.Tasks.Task created by this TaskCompletionSource.

Methods of TaskCompletionSource class in C#:

The TaskCompletionSource class in C# provides the following methods.

  • SetCanceled(): This method is used to set the underlying Task into the Canceled state.
  • SetException(Exception exception): This method is used to set the underlying Task into the Faulted State and binds it to a specified exception. Here, the parameter exception specifies the exception to binding to this Task.
  • SetException(IEnumerable<Exception> exceptions): This method is used to set the underlying Task into the Faulted State and binds a collection of exception objects to it. Here, the parameter exception specifies the collection of exceptions to bind to this Task.
  • SetResult(TResult result): This method is used to set the underlying Task into the RanToCompletion State. Here, the parameter result specifies the result value to bind to this Task.

Example to Understand How to Control the Result of a Task in C#?

Let us understand this with an example. Let’s create a method that will return a task, but it will be a task in which we will control its status. For a better understanding, please have a look at the below image. Here, we have created one method which is returning a Task and taking a string input value. First, we created an instance of the TaskCompletionSource class using one of the overloaded versions of the Constructor. Then we are checking the string value using if-else statements. If the input string value is 1 then we are calling the SetResult method on the TaskCompletionSource instance, this method will set the state of the Task (the task holds by the TaskCompletionSource object) to RanToCompletion. Next, if the string value is 2, then we are calling the SetCanceled method which will set the state of the Task to Canceled. If the value is neither 2 nor 3, then we are calling the SetException method by passing an exception object which will set the state of the Task to Faulted. Finally, we are returning the task by calling the Task property of the TaskCompletionSource class.

Example to Understand How to Control the Result of a Task in C#?

Next, in order to check whether the task is completed, faulted, or canceled, we are going to use the following three properties of the Task class.

  • IsCompleted { get; }: It returns true if the task has been completed; otherwise false.
  • IsCanceled { get; }: It returns true if the task has been completed due to being canceled; otherwise false.
  • IsFaulted { get; }: It returns true if the task has thrown an unhandled exception; otherwise false.

For this, we are creating the following method. From this method, we are calling the EvaluateValue method. The EvaluateValue method returns one task whose status we managed. Remember, if we are passing 2, then we are throwing an exception. Even if we pass 2, then also it will throw a standard task canceled exception. So, to handle those exceptions we are using the try-catch block and also printing the error message on the console window.

How to Control the Result of a Task in C# using TaskCompletionSource

Following is the Complete Example Code:

Now, run the application and enter the value as 1. You will get the following output. Is Completed as true and Is canceled and Is faulted as False.

How to Control the Result of a Task in C# using TaskCompletionSource with Examples

Now, again run the application and enter the value as 2. You will get the following output. Is Completed and Is canceled as True and Is faulted as False. As it is canceled so it will throw a task canceled exception that you can see in the Exception message.

How to Control the Result of a Task in C# using TaskCompletionSource

Now, again run the application and enter the value as 3. You will get the following output. Is Completed as True, Is canceled as False and Is Faulted as True. As we throw an exception, so you can that exception message.

How to Control the Result of a Task in C#

So, you can see with TaskCompletionSource, we have complete control over the status of the task.

Example of TaskCompletionSource With Return Value

In the previous example, if you remember we have set null, in the SetResult method. It is also possible to return some value. Let us say we want to return a string value. Then we need to pass the string value to the SetResult method. Apart from this, we need to do two more changes, First, the return type of the method will change from Task to Task<string>, and while creating the instance if the TaskCompletionSource, instead of object we need to pass a string. The following example exactly does the same.

Run the above code and enter the value as 1 and then you will get the following output. You can observe the Result.

Example of TaskCompletionSource With Return Value

In the next article, I am going to discuss Task-based Asynchronous Programming in C# with Examples. Here, in this article, I try to explain How to Control the Result of a Task in C# using TaskCompletionSource with Examples. I hope you enjoy this How to Control the Result of a Task in C# with Examples using TaskCompletionSource article.

dotnettutorials 1280x720

About the Author: Pranaya Rout

Pranaya Rout has published more than 3,000 articles in his 11-year career. Pranaya Rout has very good experience with Microsoft Technologies, Including C#, VB, ASP.NET MVC, ASP.NET Web API, EF, EF Core, ADO.NET, LINQ, SQL Server, MYSQL, Oracle, ASP.NET Core, Cloud Computing, Microservices, Design Patterns and still learning new technologies.

3 thoughts on “How to Control the Result of a Task in C#”

task result not returning

Guys, Please give your valuable feedback. And also, give your suggestions about this How to Control the Result of a Task in C# concept. If you have any better examples, you can also put them in the comment section. If you have any key points related to How to Control the Result of a Task in C#, you can also share the same.

task result not returning

Hello, Just a question: do we really need to awit for ttask in this code below ?

try { Console.WriteLine($”Is Completed: {task.IsCompleted}”); Console.WriteLine($”Is IsCanceled: {task.IsCanceled}”); Console.WriteLine($”Is IsFaulted: {task.IsFaulted}”); await task; } catch (Exception ex) { Console.WriteLine(ex.Message); } Console.WriteLine(“EvaluateValue Completed”);

If you are not awaiting the task, then it will not wait till the task is completed. In that case, if any exception occurs, your application will not handle it.

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

IMAGES

  1. SSIS Basics: Using the Execute SQL Task to Generate Result Sets

    task result not returning

  2. [Fixed!] Excel VLOOKUP Not Returning Correct Value

    task result not returning

  3. Page methods that have void/task return type are returning JSON result

    task result not returning

  4. All about SQLServer: SSIS

    task result not returning

  5. Execute SQL Task in SSIS

    task result not returning

  6. sharepoint online

    task result not returning

VIDEO

  1. Multi Statement Table Valued Functions in SQL Server

  2. 1M Subscribers on YouTube 🤩

  3. Task Result Point Table

  4. C2 E16: Choices, Choices, Choices

  5. Ticket To Finale First Task Result

  6. Online Abacus Daily Task

COMMENTS

  1. Understanding Async, Avoiding Deadlocks in C#

    What Causes a Deadlock? Task.Wait() does. That would be the end of story but sometimes it cannot be avoided, and it’s not the only case. Deadlock might also be cause by other sort of blocking ...

  2. How to handle Task result in a more elegant way

    public static class Helper {public static async Task < Result > TryAwait (this Task task, Action < Exception > errorHandler = null) {try {await task; return Result.

  3. How to Control the Result of a Task in C#

    Finally, we are returning the task by calling the Task property of the TaskCompletionSource class. Next, in order to check whether the task is completed, faulted, or canceled, we are going to use the following three properties of the Task class. IsCompleted { get; }: It returns true if the task has been completed; otherwise false.