Click here to Skip to main content
15,879,096 members
Articles / Desktop Programming / WPF

Simplifying async calls

Rate me:
Please Sign up or sign in to vote.
3.78/5 (9 votes)
1 Feb 2014CPOL 47.9K   273   13   28
How to reduce overhead and complexity of calling async methods.

Introduction

I often find myself revisiting old code to see how a actually implemented the asynchronous calls.
More than once I thought that the async "stuff" could be wrapped so I shouldn't have to remember how to implement it. 

This article is about wrapping the async call into something more easily remembered.  

Typical async use 

This example show how I typically would implement an async call.

C#
public void Backup()
{
  backupInProgress = true;
  Task<String> backup = BackupAsync();
  backup.GetAwaiter().OnCompleted(
    () =>
    {
      BackupStatus = backup.Result;
      backupInProgress = false;
    });
}

Where BackupAsync handles the async and await:

C#
private async Task<String> BackupAsync()
{
  Func<string> a = () =>
    {
      // Do stuff here
    };
  return await Task.Run(a);
}

I normally use the Result from the Function/Task to update logic or UI when the asynchronous method completes.  In the example above a property BackupStatus is set. 

Reducing the code   

The async call can be wrapped into the following method: 
C++
public static void Do(Func<T> func, Action<T> completed)
{
  Task<T> task = AsyncTask(func);
  task.GetAwaiter().OnCompleted(() =>
                                {
                                  if (!task.IsFaulted) // Check if Faulted
                                    completed(task.Result);
                                });
}

Where AsyncTask is defined as below:

C#
private static async Task<T> AsyncTask(Func<T> func)
{
  return await Task.Run(func);
}

Now I can call a Function (func) asynchronously and give the result to an Action (completed) using the following code:

C#
Async<string>.Do(Backup, UpdateUI);

Where Backup and UpdateUI is regular methods called asynchronously: 

C#
private string Backup()
{
  // Do backup
  return "Done"; // return status
}

private void UpdateUI(string status)
{
  BackupStatus = status;
}

Perfect! No more async await, but how do we handle exceptions?
Well we could create an overload that call another method if the Task has IsFaulted set:

public static void Do(Func<T> func, Action<T> completed, Action<Exception> failure)
{
  Task<T> task = AsyncTask(func);
  task.GetAwaiter().OnCompleted(() =>
    {
      if (task.IsFaulted)
        failure(task.Exception);
      else
        completed.Invoke(task.Result);
    });
}
This way we can call the Do method like this:
C#
Async<string>.Do(Backup, UpdateUI, HandleException);  

Where HandleException: 

private void HandleException(Exception parameter)
{
   // Handle exception
}  


Please look at the provided sample for additional information. 

History 

My initial thoughts.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
Denmark Denmark
Name: Niel Morgan Thomas
Born: 1970 in Denmark
Education:
Dataengineer from Odense Technical University.
More than 20 years in IT-business.
Current employment:
Cloud architect at University College Lillebaelt

Comments and Discussions

 
BugMispelled Do function declaration Pin
er.blacky3-Feb-14 10:22
er.blacky3-Feb-14 10:22 
GeneralRe: Mispelled Do function declaration Pin
Niel M.Thomas3-Feb-14 19:27
professionalNiel M.Thomas3-Feb-14 19:27 
GeneralMy vote of 4 Pin
Pranay Rana2-Feb-14 23:46
professionalPranay Rana2-Feb-14 23:46 
GeneralMy vote of 2 Pin
Paulo Zemek2-Feb-14 4:54
mvaPaulo Zemek2-Feb-14 4:54 
GeneralRe: My vote of 2 Pin
William E. Kempf3-Feb-14 4:18
William E. Kempf3-Feb-14 4:18 
GeneralRe: My vote of 2 Pin
Paulo Zemek3-Feb-14 4:24
mvaPaulo Zemek3-Feb-14 4:24 
GeneralRe: My vote of 2 Pin
William E. Kempf3-Feb-14 4:38
William E. Kempf3-Feb-14 4:38 
GeneralRe: My vote of 2 Pin
Niel M.Thomas3-Feb-14 5:47
professionalNiel M.Thomas3-Feb-14 5:47 
GeneralRe: My vote of 2 Pin
William E. Kempf3-Feb-14 6:22
William E. Kempf3-Feb-14 6:22 
GeneralRe: My vote of 2 Pin
Sacha Barber3-Feb-14 19:57
Sacha Barber3-Feb-14 19:57 
QuestionI don't understand what you are trying to accomplish here. Pin
Paulo Zemek2-Feb-14 4:53
mvaPaulo Zemek2-Feb-14 4:53 
AnswerThis is the point - Pin
Niel M.Thomas2-Feb-14 6:53
professionalNiel M.Thomas2-Feb-14 6:53 
GeneralRe: This is the point - Pin
Paulo Zemek2-Feb-14 7:21
mvaPaulo Zemek2-Feb-14 7:21 
GeneralRe: This is the point - Pin
Niel M.Thomas2-Feb-14 9:50
professionalNiel M.Thomas2-Feb-14 9:50 
GeneralRe: This is the point - Pin
Paulo Zemek2-Feb-14 10:10
mvaPaulo Zemek2-Feb-14 10:10 
GeneralRe: This is the point - Pin
Sacha Barber2-Feb-14 22:07
Sacha Barber2-Feb-14 22:07 
GeneralRe: This is the point - Pin
Niel M.Thomas2-Feb-14 23:02
professionalNiel M.Thomas2-Feb-14 23:02 
AnswerRe: I don't understand what you are trying to accomplish here. Pin
Sacha Barber2-Feb-14 19:12
Sacha Barber2-Feb-14 19:12 
GeneralRe: I don't understand what you are trying to accomplish here. Pin
Paulo Zemek3-Feb-14 1:58
mvaPaulo Zemek3-Feb-14 1:58 
QuestionI would say I see typical usage more like this Pin
Sacha Barber2-Feb-14 0:35
Sacha Barber2-Feb-14 0:35 
AnswerRe: I would say I see typical usage more like this Pin
Niel M.Thomas2-Feb-14 2:23
professionalNiel M.Thomas2-Feb-14 2:23 
GeneralRe: I would say I see typical usage more like this Pin
Sacha Barber2-Feb-14 19:08
Sacha Barber2-Feb-14 19:08 
GeneralRe: I would say I see typical usage more like this Pin
William E. Kempf3-Feb-14 4:30
William E. Kempf3-Feb-14 4:30 
GeneralRe: I would say I see typical usage more like this Pin
Sacha Barber3-Feb-14 19:52
Sacha Barber3-Feb-14 19:52 
GeneralRe: I would say I see typical usage more like this Pin
William E. Kempf4-Feb-14 3:49
William E. Kempf4-Feb-14 3:49 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.