I've determined by experiment that the following types are sufficient in order to make the C# 5 compiler process basic async
/await
code (even when targeting .NET Framework version 2!):
IAsyncStateMachine
INotifyCompletion
(no member declarations needed)ICriticalNotifyCompletion
(no member declarations needed)AsyncVoidMethodBuilder
AsyncTaskMethodBuilder
AsyncTaskMethodBuilder<TResult>
Task
(no member declarations needed)Task<TResult>
(no member declarations needed)
The most minimal declarations for these that I've found to be acceptable to the C# compiler follow below.
namespace System.Threading.Tasks
{
abstract class Task { }
abstract class Task<TResult> : Task { }
}
namespace System.Runtime.CompilerServices
{
interface INotifyCompletion { }
interface ICriticalNotifyCompletion { }
interface IAsyncStateMachine
{
void MoveNext();
void SetStateMachine(IAsyncStateMachine stateMachine);
}
struct AsyncVoidMethodBuilder
{
public static AsyncVoidMethodBuilder Create() { … }
public void Start<TStateMachine>(ref TStateMachine stateMachine)
// where TStateMachine : IAsyncStateMachine
{ … }
public void SetResult() { … }
public void SetException(Exception exception) { … }
public void SetStateMachine(IAsyncStateMachine stateMachine) { … }
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
// where TAwaiter : INotifyCompletion
// where TStateMachine : IAsyncStateMachine
{ … }
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
// where TAwaiter : ICriticalNotifyCompletion
// where TStateMachine : IAsyncStateMachine
{ … }
}
struct AsyncTaskMethodBuilder
{
public Task Task { get { … } }
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
// where TAwaiter : INotifyCompletion
// where TStateMachine : IAsyncStateMachine
{ … }
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
// where TAwaiter : ICriticalNotifyCompletion
// where TStateMachine : IAsyncStateMachine
{ … }
public static AsyncTaskMethodBuilder Create() { … }
public void SetException(Exception exception) { … }
public void SetResult() { … }
public void SetStateMachine(IAsyncStateMachine stateMachine) { … }
public void Start<TStateMachine>(ref TStateMachine stateMachine)
// where TStateMachine : IAsyncStateMachine
{ … }
}
struct AsyncTaskMethodBuilder<TResult>
{
public static AsyncTaskMethodBuilder<TResult> Create() { … }
public void Start<TStateMachine>(ref TStateMachine stateMachine)
// where TStateMachine : IAsyncStateMachine
{ … }
public void SetResult(TResult result) { … }
public void SetException(Exception exception) { … }
public void SetStateMachine(IAsyncStateMachine stateMachine) { … }
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
// where TAwaiter : INotifyCompletion
// where TStateMachine : IAsyncStateMachine
{ … }
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
// where TAwaiter : ICriticalNotifyCompletion
// where TStateMachine : IAsyncStateMachine
{ … }
public Task<TResult> Task { get { … } }
}
}
(I am throwing a NotImplementedException
wherever it says { … }
.)