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.
public void Backup()
{
backupInProgress = true;
Task<String> backup = BackupAsync();
backup.GetAwaiter().OnCompleted(
() =>
{
BackupStatus = backup.Result;
backupInProgress = false;
});
}
Where BackupAsync handles the async and await:
private async Task<String> BackupAsync()
{
Func<string> a = () =>
{
};
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:
public static void Do(Func<T> func, Action<T> completed)
{
Task<T> task = AsyncTask(func);
task.GetAwaiter().OnCompleted(() =>
{
if (!task.IsFaulted) completed(task.Result);
});
}
Where AsyncTask is defined as below:
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:
Async<string>.Do(Backup, UpdateUI);
Where Backup and UpdateUI is regular methods called asynchronously:
private string Backup()
{
return "Done";
}
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:
Async<string>.Do(Backup, UpdateUI, HandleException);
Where HandleException:
private void HandleException(Exception parameter)
{
}
Please look at the provided sample for additional information.
History
My initial thoughts.