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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | /// <summary> /// Get the result of a task in contexts where the "await" keyword may be prohibited /// </summary> /// <typeparam name="T"> /// The return type for the task /// </typeparam> /// <param name="task"> /// The task to be awaited /// </param> /// <returns> /// The result of the task /// </returns> public static T TaskResult<T>(Task<T> task) { Task.WaitAll(task); return task.Result; } |
And, in places where you can’t do something like this…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | /// <summary> /// A horribly contrived example class /// </summary> /// <remarks> /// Don't ever structure your POCOs this way, unless EF is handling the navigation properties /// </remarks> public class ExampleClass { /// <summary> /// A contrived ID to a dependent entity /// </summary> 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); } } } |
…you can instead do this in that “DependentEntity” property…
1 2 3 4 5 6 7 8 9 10 11 | /// <summary> /// The contrived dependent entity /// </summary> public DependentEntity DependentEntity { get { return UtilClass.TaskResult<DependentEntity>(Data.DependentEntities .FirstOrDefaultAsync(entity => entity.ID == ForeignKeyID)); } } |