bitbadger.solutions-blog-theme/source/_posts/2014/a-handy-c-sharp-async-utility-method.md
Daniel J. Summers 67dcb2f77c Initial import
brought over all the files from the Jekyll version, fixed categories,
reformatted for different markdown processor
2017-09-02 11:49:59 -05:00

2.6 KiB

layout title author date categories tags summary
post A Handy C# Async Utility Method Daniel 2014-08-04 19:48:43
Programming
.NET
C#
asynchronous
c#
utility
Using async when you can't use async

In the course of writing C# code utilizing the new (for 4.5.1) Task-based asynchronous programming, I've run across a couple of places where the await keyword either is not allowed (a catch block or a property accessor) or the async keyword greatly complicates the syntax (lambda expressions). I've found myself writing this method for two different projects, and so I thought I would drop this Q&D, more-comments-than-code utility method here for others to use if you see the need.

(UPDATE: This works well in console applications; it can cause deadlocks in desktop and web apps. Test before you rely on it.)

{% codeblock lang:csharp %} ///

/// Get the result of a task in contexts where the "await" keyword may be prohibited /// /// The return type for the task /// The task to be awaited /// The result of the task public static T TaskResult(Task task) { Task.WaitAll(task); return task.Result; } {% endcodeblock %}

And, in places where you can't do something like this...

{% codeblock ExampleClass.cs lang:csharp %} ///

/// A horribly contrived example class /// /// Don't ever structure your POCOs this way, unless EF is handling the navigation properties public class ExampleClass { /// /// A contrived ID to a dependent entity /// public int ForeignKeyID { get; set; }

/// <summary>
/// The contrived dependent entity
/// </summary>
public DependentEntity DependentEntity
{
    get
    {
        // Does not compile; can't use await without async, can't mark a property as async
        return await Data.DependentEntities
            .FirstOrDefaultAsync(entity => entity.ID == ForeignKeyID);
    }
}

} {% endcodeblock %}

...you can instead do this in that "DependentEntity" property...

{% codeblock lang:csharp %} ///

/// The contrived dependent entity /// public DependentEntity DependentEntity { get { return UtilClass.TaskResult(Data.DependentEntities .FirstOrDefaultAsync(entity => entity.ID == ForeignKeyID)); } } {% endcodeblock %}