using System; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Security; namespace ETModel { public struct AsyncETTaskMethodBuilder { private ETTaskCompletionSource tcs; private Action moveNext; // 1. Static Create method. [DebuggerHidden] public static AsyncETTaskMethodBuilder Create() { AsyncETTaskMethodBuilder builder = new AsyncETTaskMethodBuilder(); return builder; } // 2. TaskLike Task property. [DebuggerHidden] public ETTask Task { get { if (this.tcs != null) { return this.tcs.Task; } if (moveNext == null) { return ETTask.CompletedTask; } this.tcs = new ETTaskCompletionSource(); return this.tcs.Task; } } // 3. SetException [DebuggerHidden] public void SetException(Exception exception) { if (this.tcs == null) { this.tcs = new ETTaskCompletionSource(); } if (exception is OperationCanceledException ex) { this.tcs.TrySetCanceled(ex); } else { this.tcs.TrySetException(exception); } } // 4. SetResult [DebuggerHidden] public void SetResult() { if (moveNext == null) { } else { if (this.tcs == null) { this.tcs = new ETTaskCompletionSource(); } this.tcs.TrySetResult(); } } // 5. AwaitOnCompleted [DebuggerHidden] public void AwaitOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine { if (moveNext == null) { if (this.tcs == null) { this.tcs = new ETTaskCompletionSource(); // built future. } var runner = new MoveNextRunner(); moveNext = runner.Run; runner.StateMachine = stateMachine; // set after create delegate. } awaiter.OnCompleted(moveNext); } // 6. AwaitUnsafeOnCompleted [DebuggerHidden] [SecuritySafeCritical] public void AwaitUnsafeOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine { if (moveNext == null) { if (this.tcs == null) { this.tcs = new ETTaskCompletionSource(); // built future. } var runner = new MoveNextRunner(); moveNext = runner.Run; runner.StateMachine = stateMachine; // set after create delegate. } awaiter.UnsafeOnCompleted(moveNext); } // 7. Start [DebuggerHidden] public void Start(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine { stateMachine.MoveNext(); } // 8. SetStateMachine [DebuggerHidden] public void SetStateMachine(IAsyncStateMachine stateMachine) { } } public struct ETAsyncTaskMethodBuilder { private T result; private ETTaskCompletionSource tcs; private Action moveNext; // 1. Static Create method. [DebuggerHidden] public static ETAsyncTaskMethodBuilder Create() { var builder = new ETAsyncTaskMethodBuilder(); return builder; } // 2. TaskLike Task property. [DebuggerHidden] public ETTask Task { get { if (this.tcs != null) { return new ETTask(this.tcs); } if (moveNext == null) { return new ETTask(result); } this.tcs = new ETTaskCompletionSource(); return this.tcs.Task; } } // 3. SetException [DebuggerHidden] public void SetException(Exception exception) { if (this.tcs == null) { this.tcs = new ETTaskCompletionSource(); } if (exception is OperationCanceledException ex) { this.tcs.TrySetCanceled(ex); } else { this.tcs.TrySetException(exception); } } // 4. SetResult [DebuggerHidden] public void SetResult(T ret) { if (moveNext == null) { this.result = ret; } else { if (this.tcs == null) { this.tcs = new ETTaskCompletionSource(); } this.tcs.TrySetResult(ret); } } // 5. AwaitOnCompleted [DebuggerHidden] public void AwaitOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine { if (moveNext == null) { if (this.tcs == null) { this.tcs = new ETTaskCompletionSource(); // built future. } var runner = new MoveNextRunner(); moveNext = runner.Run; runner.StateMachine = stateMachine; // set after create delegate. } awaiter.OnCompleted(moveNext); } // 6. AwaitUnsafeOnCompleted [DebuggerHidden] [SecuritySafeCritical] public void AwaitUnsafeOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine { if (moveNext == null) { if (this.tcs == null) { this.tcs = new ETTaskCompletionSource(); // built future. } var runner = new MoveNextRunner(); moveNext = runner.Run; runner.StateMachine = stateMachine; // set after create delegate. } awaiter.UnsafeOnCompleted(moveNext); } // 7. Start [DebuggerHidden] public void Start(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine { stateMachine.MoveNext(); } // 8. SetStateMachine [DebuggerHidden] public void SetStateMachine(IAsyncStateMachine stateMachine) { } } }