Skip to content

Instantly share code, notes, and snippets.

@Krumelur
Created December 4, 2015 07:36
Show Gist options
  • Save Krumelur/39c44b45dfc658bb633c to your computer and use it in GitHub Desktop.
Save Krumelur/39c44b45dfc658bb633c to your computer and use it in GitHub Desktop.
Shows how to make any class "awaitable".
using System;
using System.Threading.Tasks;
using System.Runtime.CompilerServices;
namespace AwaitTest
{
class MainClass
{
public static void Main (string[] args)
{
MainAsync().Wait();
Console.ReadLine();
}
async static Task MainAsync()
{
var foo = new Foo();
// We can "await" foo - but it's not a Task, nor does it implement some "IAwaiter" or "IAwaitable" interface.
// It simply follows some conventions which make Foo implicitly awaitable.
await foo;
}
}
// To be "awaitable":
// - Interface INotifyCompletion must be implemented
// - A GetResult() method must be there (returning void or an actual result)
// - it must have a bool IsCompleted property.
//
// The implementation is just meant to demonstrate how something can be made awaitable!
// It is not doing anything async!
//
// Good reference with more information: http://weblogs.asp.net/dixin/understanding-c-sharp-async-await-2-awaitable-awaiter-pattern
public class Foo : INotifyCompletion
{
#region INotifyCompletion implementation
public void OnCompleted (Action continuation)
{
this.IsCompleted = true;
continuation?.Invoke();
}
#endregion
public bool IsCompleted
{
get;
private set;
}
public void GetResult()
{
Console.WriteLine("We're done!");
}
public Foo GetAwaiter()
{
// Foo itself is the awaitable.
return this;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment