#if NET20 || NET30 || NET35 || NET40 || !NET_4_6 // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Runtime.InteropServices; using System.Security; using System.Threading.Tasks; namespace System.Runtime.CompilerServices { /// Represents a builder for asynchronous methods that returns a . /// The type of the result. [StructLayout(LayoutKind.Auto)] public struct AsyncValueTaskMethodBuilder { /// The to which most operations are delegated. private AsyncTaskMethodBuilder _methodBuilder; /// The result for this builder, if it's completed before any awaits occur. private TResult _result; /// true if contains the synchronous result for the async method; otherwise, false. private bool _haveResult; /// true if the builder should be used for setting/getting the result; otherwise, false. private bool _useBuilder; /// Creates an instance of the struct. /// The initialized instance. public static AsyncValueTaskMethodBuilder Create() { return new AsyncValueTaskMethodBuilder() { _methodBuilder = AsyncTaskMethodBuilder.Create() }; } /// Begins running the builder with the associated state machine. /// The type of the state machine. /// The state machine instance, passed by reference. public void Start(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine { _methodBuilder.Start(ref stateMachine); // will provide the right ExecutionContext semantics } /// Associates the builder with the specified state machine. /// The state machine instance to associate with the builder. public void SetStateMachine(IAsyncStateMachine stateMachine) { _methodBuilder.SetStateMachine(stateMachine); } /// Marks the task as successfully completed. /// The result to use to complete the task. public void SetResult(TResult result) { if (_useBuilder) { _methodBuilder.SetResult(result); } else { _result = result; _haveResult = true; } } /// Marks the task as failed and binds the specified exception to the task. /// The exception to bind to the task. public void SetException(Exception exception) { _methodBuilder.SetException(exception); } /// Gets the task for this builder. public ValueTask Task { get { if (_haveResult) { return new ValueTask(_result); } else { _useBuilder = true; return new ValueTask(_methodBuilder.Task); } } } /// Schedules the state machine to proceed to the next action when the specified awaiter completes. /// The type of the awaiter. /// The type of the state machine. /// the awaiter /// The state machine. public void AwaitOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine { _useBuilder = true; _methodBuilder.AwaitOnCompleted(ref awaiter, ref stateMachine); } /// Schedules the state machine to proceed to the next action when the specified awaiter completes. /// The type of the awaiter. /// The type of the state machine. /// the awaiter /// The state machine. [SecuritySafeCritical] public void AwaitUnsafeOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine { _useBuilder = true; _methodBuilder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine); } } } #endif