Delete PROJECTN ifdefs from Corelib (dotnet/coreclr#26058)
[mono-project.git] / netcore / System.Private.CoreLib / shared / System / Runtime / CompilerServices / AsyncIteratorMethodBuilder.cs
bloba18b685358b1742d9d0017818cb3dab5492a675e
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
5 using System.Runtime.InteropServices;
6 using System.Threading;
8 namespace System.Runtime.CompilerServices
10 /// <summary>Represents a builder for asynchronous iterators.</summary>
11 [StructLayout(LayoutKind.Auto)]
12 public struct AsyncIteratorMethodBuilder
14 // AsyncIteratorMethodBuilder is used by the language compiler as part of generating
15 // async iterators. For now, the implementation just wraps AsyncTaskMethodBuilder, as
16 // most of the logic is shared. However, in the future this could be changed and
17 // optimized. For example, we do need to allocate an object (once) to flow state like
18 // ExecutionContext, which AsyncTaskMethodBuilder handles, but it handles it by
19 // allocating a Task-derived object. We could optimize this further by removing
20 // the Task from the hierarchy, but in doing so we'd also lose a variety of optimizations
21 // related to it, so we'd need to replicate all of those optimizations (e.g. storing
22 // that box object directly into a Task's continuation field).
24 private AsyncTaskMethodBuilder _methodBuilder; // mutable struct; do not make it readonly
26 /// <summary>Creates an instance of the <see cref="AsyncIteratorMethodBuilder"/> struct.</summary>
27 /// <returns>The initialized instance.</returns>
28 public static AsyncIteratorMethodBuilder Create() =>
29 // _methodBuilder should be initialized to AsyncTaskMethodBuilder.Create(), but on coreclr
30 // that Create() is a nop, so we can just return the default here.
31 default;
33 /// <summary>Invokes <see cref="IAsyncStateMachine.MoveNext"/> on the state machine while guarding the <see cref="ExecutionContext"/>.</summary>
34 /// <typeparam name="TStateMachine">The type of the state machine.</typeparam>
35 /// <param name="stateMachine">The state machine instance, passed by reference.</param>
36 [MethodImpl(MethodImplOptions.AggressiveInlining)]
37 public void MoveNext<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine =>
38 AsyncMethodBuilderCore.Start(ref stateMachine);
40 /// <summary>Schedules the state machine to proceed to the next action when the specified awaiter completes.</summary>
41 /// <typeparam name="TAwaiter">The type of the awaiter.</typeparam>
42 /// <typeparam name="TStateMachine">The type of the state machine.</typeparam>
43 /// <param name="awaiter">The awaiter.</param>
44 /// <param name="stateMachine">The state machine.</param>
45 public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
46 where TAwaiter : INotifyCompletion
47 where TStateMachine : IAsyncStateMachine =>
48 _methodBuilder.AwaitOnCompleted(ref awaiter, ref stateMachine);
50 /// <summary>Schedules the state machine to proceed to the next action when the specified awaiter completes.</summary>
51 /// <typeparam name="TAwaiter">The type of the awaiter.</typeparam>
52 /// <typeparam name="TStateMachine">The type of the state machine.</typeparam>
53 /// <param name="awaiter">The awaiter.</param>
54 /// <param name="stateMachine">The state machine.</param>
55 public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
56 where TAwaiter : ICriticalNotifyCompletion
57 where TStateMachine : IAsyncStateMachine =>
58 _methodBuilder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine);
60 /// <summary>Marks iteration as being completed, whether successfully or otherwise.</summary>
61 public void Complete() => _methodBuilder.SetResult();
63 /// <summary>Gets an object that may be used to uniquely identify this builder to the debugger.</summary>
64 internal object ObjectIdForDebugger => _methodBuilder.ObjectIdForDebugger;