Be aware to not await null

The addition of async/await to the C# language specification made it easier to write asynchronous code. However while writing code, you’ll end up in some cases where you don’t have a Task to return in a certain path of your logic or you have a virtual empty method.

The logic solution in this case would be to return null. However awaiting the method call that returns null, will throw a NullReferenceException. Always return a Task from the type defined in the method declaration. This can easily be done with a Task.FromResult call. I’ve made a small wrapper to do the job:

/// <summary>
/// Wrapper utility to return an empty task instead of null.
/// Returning null might throw an exception on executing code.
/// </summary>
/// <typeparam name="T"></typeparam>
public static class Empty<T>
{
    private static readonly Task<T> _task = System.Threading.Tasks.Task.FromResult(default(T));

    public static Task<T> Task { get { return _task; } }
}

An example how to use it with multiple return paths:

public Task<List<string>> GetSearchResultsAsync(string searchString)
{
    if (!string.IsNullOrEmpty(searchString))
    {
        return _searchService.SearchAsync(resultString); // async service call returning Task<List<string>>
    }

    return Empty<List<string>>.Task;
}

When returning a non generic Task, you can use object (or actually any type) for type T:

public virtual Task LoadDataAsync(string deepLink, NavigationMode navigationMode, Dictionary<string, object> viewModelState)
{
    return Empty<object>.Task; // null would throw exception on await
}
Licensed under CC BY-NC-SA 4.0; code samples licensed under MIT.
comments powered by Disqus
Built with Hugo - Based on Theme Stack designed by Jimmy