In the previous post, we saw a small introduction to the features that .Net has to work asynchronously. In this post, we will see how to create our asynchronous methods, how to handle exceptions, and good practices when using this paradigm.
Our asynchronous method
We should always think that our code should not be too long. Let's remember that our code must be as clean as possible, therefore, we are going to refactor the code from the previous post, which was the following:
private async void button_Click(object sender, RoutedEventArgs e)
{
using (var client = new HttpClient())
{
var result = await client.GetAsync($"https://localhost:44356/api/customers/search/" + search);
try {
result.EnsureSuccessStatusCode();
var content = await result.Content.ReadAsStringAsync();
var data = JsonConvert.DeserializeObject<IEnumerable<Customer>>(content);
CustomersGrid.ItemsSource = data;
} catch (Exception ex) {
txtOut.Text += ex.Message;
}
}
}
We will make some changes, we will create a method that we will call GetPeople (). We will make sure that our application does not modify its behavior despite being in a separate method. We will modify our code. It will look like this:
private async void button_Click(object sender, RoutedEventArgs e)
{
await GetPeople(search);
}
public async Task GetPeople(string search) {
using (var client = new HttpClient())
{
var result = await client.GetAsync($"https://localhost:44356/api/customers/search/" + search);
try
{
result.EnsureSuccessStatusCode();
var content = await result.Content.ReadAsStringAsync();
var data = JsonConvert.DeserializeObject<IEnumerable<Customer>>(content);
CustomersGrid.ItemsSource = data;
}
catch (Exception ex)
{
txtOut.Text += ex.Message;
}
}
}
The first thing we can notice is that our GetPeople () method is declared as async and Task. Note: we should not do async methods that return a void type, we should only use it when they are Event Handlers.
Declaring it as Task means that the method will automatically return a reference to the operation that is in progress and at some point, it will be invoked waiting for the resolution. Visual Studio will not show any errors, this is because a method declared as an async task must explicitly return something and the compiler will take care of it.
In the click event, we invoke GetPeople () and declare it with the await keyword so that the code waits. Let's see in the image that nothing has changed:
It is very easy to refactor your code by creating an asynchronous method. By doing so we made our code a bit more readable. Remember, again, that this approach can be applied in any environment of .Net, ASP.Net, console, Xamarin, etc.
Exceptions
Our methods can fail. Suppose our method is calling the API but it is not available at the moment. Our application will fail. For this reason, the await keyword is so important. This guarantees that the exception is handled, and if we do not use it, the application will never know that an exception has occurred.
Visual Studio warns us when we have a call to a method that returns a Task and is not being invoked with the word await.
Another example would be, what happens if we use a try..catch block?
try
{
GetPeople(search);
}
catch (Exception)
{
throw;
}
Exactly the same would happen, the exception will not be handled. But if we add the await keyword we can handle the exception.
Another important point, async methods should not be void. The reason is that void methods cannot be handled by their exceptions because they return nothing. By using Task we make sure that something is returned.
For this reason, the await and async Task combination are very important. Thanks to this combination we can ensure that we can handle exceptions. The method will return a type and when invoked it will wait for something to happen.
Good Practices and Conclusions
Where we can use these practices in .Net:
- Windows Presentation Foundation
- Windows Forms
- Xamarin
- Console apps
- Asp.Net
We can use it in any type of .Net application we need. The only difference is that ASP.Net does not have a user interface but it will help us to lighten the load on the webserver.
Let's summarize what is wrong and what is correct:
I hope that the information is useful to you and covers all the needs that arise. In future posts, I will touch on more topics on synchronous and parallel programming.
Top comments (0)