diff --git a/Source/MorseCode.ITask/MorseCode.ITask.sln.DotSettings b/Source/MorseCode.ITask/MorseCode.ITask.sln.DotSettings
index 103a2c2..85b69cc 100644
--- a/Source/MorseCode.ITask/MorseCode.ITask.sln.DotSettings
+++ b/Source/MorseCode.ITask/MorseCode.ITask.sln.DotSettings
@@ -1,12 +1,12 @@
--------------------------------------------------------------------------------------------------------------------
-<copyright file="$FILENAME$" company="MorseCode Software">
-Copyright (c) $CURRENT_YEAR$ MorseCode Software
+<copyright file="${File.FileName}" company="MorseCode Software">
+Copyright (c) ${CurrentDate.Year} MorseCode Software
</copyright>
<summary>
The MIT License (MIT)
-Copyright (c) $CURRENT_YEAR$ MorseCode Software
+Copyright (c) ${CurrentDate.Year} MorseCode Software
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -27,4 +27,5 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
</summary>
--------------------------------------------------------------------------------------------------------------------
- 6
\ No newline at end of file
+ 6
+ True
\ No newline at end of file
diff --git a/Source/MorseCode.ITask/Tests/TaskInterfaceAsyncMethodBuilderTests.cs b/Source/MorseCode.ITask/Tests/TaskInterfaceAsyncMethodBuilderTests.cs
index c5f8666..7694676 100644
--- a/Source/MorseCode.ITask/Tests/TaskInterfaceAsyncMethodBuilderTests.cs
+++ b/Source/MorseCode.ITask/Tests/TaskInterfaceAsyncMethodBuilderTests.cs
@@ -1,12 +1,17 @@
-using NUnit.Framework;
+using System;
using System.Linq;
+using System.Text.RegularExpressions;
using System.Threading.Tasks;
+using NUnit.Framework;
+using NUnit.Framework.Legacy;
namespace MorseCode.ITask.Tests
{
[TestFixture]
public class TaskInterfaceAsyncMethodBuilderTests
{
+ private const string StackTraceRedactionPattern = "\\w__[\\w_]+(?=[()<>.])|(?<=\\(\\)) in [^\r\n]+";
+
[Test]
public async Task TaskInterfaceAsyncMethodBuilderTask()
{
@@ -18,6 +23,88 @@ async ITask TaskInterfaceAsyncMethodBuilderTaskMethodAsync()
await Task.Delay(50).ConfigureAwait(false);
}
+ [Test]
+ [SetUICulture("")]
+ public void TaskInterfaceAsyncMethodBuilderTaskWithException()
+ {
+ var exception = Assert.ThrowsAsync(async () =>
+ await TaskInterfaceAsyncMethodBuilderTaskWithExceptionMethodAsync().ConfigureAwait(false));
+ Assert.AreEqual("Test-Case Exception", exception.Message);
+ var redactedStackTrace = Regex.Replace(exception.StackTrace, StackTraceRedactionPattern, "");
+#if NET6_0_OR_GREATER
+ Assert.AreEqual(
+ """
+ at MorseCode.ITask.Tests.TaskInterfaceAsyncMethodBuilderTests.TaskInterfaceAsyncMethodBuilderTaskWithExceptionMethodAsync()
+ at MorseCode.ITask.Tests.TaskInterfaceAsyncMethodBuilderTests.()
+ at NUnit.Framework.Internal.TaskAwaitAdapter.GenericAdapter`1.BlockUntilCompleted()
+ at NUnit.Framework.Internal.MessagePumpStrategy.NoMessagePumpStrategy.WaitForCompletion(AwaitAdapter awaiter)
+ at NUnit.Framework.Internal.AsyncToSyncAdapter.Await[TResult](TestExecutionContext context, Func`1 invoke)
+ at NUnit.Framework.Internal.AsyncToSyncAdapter.Await(TestExecutionContext context, Func`1 invoke)
+ at NUnit.Framework.Assert.ThrowsAsync(IResolveConstraint expression, AsyncTestDelegate code, String message, Object[] args)
+ """,
+ redactedStackTrace);
+#else
+ StringAssert.StartsWith(
+ """
+ at MorseCode.ITask.Tests.TaskInterfaceAsyncMethodBuilderTests..MoveNext()
+ --- End of stack trace from previous location where exception was thrown ---
+ at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
+ at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
+ at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult()
+ at MorseCode.ITask.ConfiguredTaskAwaiterWrapper.MorseCode.ITask.IAwaiter.GetResult()
+ at MorseCode.ITask.Tests.TaskInterfaceAsyncMethodBuilderTests.<>d.MoveNext()
+ --- End of stack trace from previous location where exception was thrown ---
+ at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
+ at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
+ """,
+ redactedStackTrace);
+#endif
+ }
+
+ [Test]
+ [SetUICulture("")]
+ public void TaskInterfaceAsyncMethodBuilderTaskWithExceptionNoConfigure()
+ {
+ var exception = Assert.ThrowsAsync(async () =>
+ await TaskInterfaceAsyncMethodBuilderTaskWithExceptionMethodAsync());
+ Assert.AreEqual("Test-Case Exception", exception.Message);
+ var redactedStackTrace = Regex.Replace(exception.StackTrace, StackTraceRedactionPattern, "");
+#if NET6_0_OR_GREATER
+ Assert.AreEqual(
+ """
+ at MorseCode.ITask.Tests.TaskInterfaceAsyncMethodBuilderTests.TaskInterfaceAsyncMethodBuilderTaskWithExceptionMethodAsync()
+ at MorseCode.ITask.Tests.TaskInterfaceAsyncMethodBuilderTests.()
+ at NUnit.Framework.Internal.TaskAwaitAdapter.GenericAdapter`1.BlockUntilCompleted()
+ at NUnit.Framework.Internal.MessagePumpStrategy.NoMessagePumpStrategy.WaitForCompletion(AwaitAdapter awaiter)
+ at NUnit.Framework.Internal.AsyncToSyncAdapter.Await[TResult](TestExecutionContext context, Func`1 invoke)
+ at NUnit.Framework.Internal.AsyncToSyncAdapter.Await(TestExecutionContext context, Func`1 invoke)
+ at NUnit.Framework.Assert.ThrowsAsync(IResolveConstraint expression, AsyncTestDelegate code, String message, Object[] args)
+ """,
+ redactedStackTrace);
+#else
+ StringAssert.StartsWith(
+ """
+ at MorseCode.ITask.Tests.TaskInterfaceAsyncMethodBuilderTests..MoveNext()
+ --- End of stack trace from previous location where exception was thrown ---
+ at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
+ at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
+ at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
+ at MorseCode.ITask.TaskAwaiterWrapper.MorseCode.ITask.IAwaiter.GetResult()
+ at MorseCode.ITask.Tests.TaskInterfaceAsyncMethodBuilderTests.<>d.MoveNext()
+ --- End of stack trace from previous location where exception was thrown ---
+ at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
+ at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
+ """,
+ redactedStackTrace);
+#endif
+ }
+
+ async ITask TaskInterfaceAsyncMethodBuilderTaskWithExceptionMethodAsync()
+ {
+ await Task.Delay(50).ConfigureAwait(false);
+ throw new Exception("Test-Case Exception");
+ }
+
[Test]
public async Task TaskInterfaceAsyncMethodBuilderResultTask()
{
@@ -35,5 +122,87 @@ async ITask TaskInterfaceAsyncMethodBuilderResultTaskMethodAsync()
}));
return results.Length;
}
+
+ [Test]
+ [SetUICulture("")]
+ public void TaskInterfaceAsyncMethodBuilderResultTaskWithException()
+ {
+ var exception = Assert.ThrowsAsync(async () =>
+ await TaskInterfaceAsyncMethodBuilderResultTaskWithExceptionMethodAsync().ConfigureAwait(false));
+ Assert.AreEqual("Test-Case Exception", exception.Message);
+ var redactedStackTrace = Regex.Replace(exception.StackTrace, StackTraceRedactionPattern, "");
+#if NET6_0_OR_GREATER
+ Assert.AreEqual(
+ """
+ at MorseCode.ITask.Tests.TaskInterfaceAsyncMethodBuilderTests.TaskInterfaceAsyncMethodBuilderResultTaskWithExceptionMethodAsync()
+ at MorseCode.ITask.Tests.TaskInterfaceAsyncMethodBuilderTests.()
+ at NUnit.Framework.Internal.TaskAwaitAdapter.GenericAdapter`1.BlockUntilCompleted()
+ at NUnit.Framework.Internal.MessagePumpStrategy.NoMessagePumpStrategy.WaitForCompletion(AwaitAdapter awaiter)
+ at NUnit.Framework.Internal.AsyncToSyncAdapter.Await[TResult](TestExecutionContext context, Func`1 invoke)
+ at NUnit.Framework.Internal.AsyncToSyncAdapter.Await(TestExecutionContext context, Func`1 invoke)
+ at NUnit.Framework.Assert.ThrowsAsync(IResolveConstraint expression, AsyncTestDelegate code, String message, Object[] args)
+ """,
+ redactedStackTrace);
+#else
+ StringAssert.StartsWith(
+ """
+ at MorseCode.ITask.Tests.TaskInterfaceAsyncMethodBuilderTests..MoveNext()
+ --- End of stack trace from previous location where exception was thrown ---
+ at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
+ at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
+ at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
+ at MorseCode.ITask.ConfiguredTaskAwaiterWrapper`1.MorseCode.ITask.IAwaiter.GetResult()
+ at MorseCode.ITask.Tests.TaskInterfaceAsyncMethodBuilderTests.<>d.MoveNext()
+ --- End of stack trace from previous location where exception was thrown ---
+ at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
+ at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
+ """,
+ redactedStackTrace);
+#endif
+ }
+
+ [Test]
+ [SetUICulture("")]
+ public void TaskInterfaceAsyncMethodBuilderResultTaskWithExceptionNoConfigure()
+ {
+ var exception = Assert.ThrowsAsync(async () =>
+ await TaskInterfaceAsyncMethodBuilderResultTaskWithExceptionMethodAsync());
+ Assert.AreEqual("Test-Case Exception", exception.Message);
+ var redactedStackTrace = Regex.Replace(exception.StackTrace, StackTraceRedactionPattern, "");
+#if NET6_0_OR_GREATER
+ Assert.AreEqual(
+ """
+ at MorseCode.ITask.Tests.TaskInterfaceAsyncMethodBuilderTests.TaskInterfaceAsyncMethodBuilderResultTaskWithExceptionMethodAsync()
+ at MorseCode.ITask.Tests.TaskInterfaceAsyncMethodBuilderTests.()
+ at NUnit.Framework.Internal.TaskAwaitAdapter.GenericAdapter`1.BlockUntilCompleted()
+ at NUnit.Framework.Internal.MessagePumpStrategy.NoMessagePumpStrategy.WaitForCompletion(AwaitAdapter awaiter)
+ at NUnit.Framework.Internal.AsyncToSyncAdapter.Await[TResult](TestExecutionContext context, Func`1 invoke)
+ at NUnit.Framework.Internal.AsyncToSyncAdapter.Await(TestExecutionContext context, Func`1 invoke)
+ at NUnit.Framework.Assert.ThrowsAsync(IResolveConstraint expression, AsyncTestDelegate code, String message, Object[] args)
+ """,
+ redactedStackTrace);
+#else
+ StringAssert.StartsWith(
+ """
+ at MorseCode.ITask.Tests.TaskInterfaceAsyncMethodBuilderTests..MoveNext()
+ --- End of stack trace from previous location where exception was thrown ---
+ at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
+ at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
+ at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
+ at MorseCode.ITask.TaskAwaiterWrapper`1.MorseCode.ITask.IAwaiter.GetResult()
+ at MorseCode.ITask.Tests.TaskInterfaceAsyncMethodBuilderTests.<>d.MoveNext()
+ --- End of stack trace from previous location where exception was thrown ---
+ at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
+ at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
+ """,
+ redactedStackTrace);
+#endif
+ }
+
+ async ITask TaskInterfaceAsyncMethodBuilderResultTaskWithExceptionMethodAsync()
+ {
+ await Task.Delay(50).ConfigureAwait(false);
+ throw new Exception("Test-Case Exception");
+ }
}
}
diff --git a/Source/MorseCode.ITask/Tests/Tests.csproj b/Source/MorseCode.ITask/Tests/Tests.csproj
index 473787f..14b6b64 100644
--- a/Source/MorseCode.ITask/Tests/Tests.csproj
+++ b/Source/MorseCode.ITask/Tests/Tests.csproj
@@ -1,9 +1,10 @@
- netcoreapp1.0;netcoreapp2.0;net45
+ net8.0;net10.0;net462
MorseCode.ITask.Tests
MorseCode.ITask.Tests
+ 14
@@ -12,12 +13,15 @@
-
-
-
-
-
-
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
diff --git a/Source/MorseCode.ITask/_Root/AsyncMethodBuilderAttribute.cs b/Source/MorseCode.ITask/_Root/AsyncMethodBuilderAttribute.cs
index e735a6e..e3f34b6 100644
--- a/Source/MorseCode.ITask/_Root/AsyncMethodBuilderAttribute.cs
+++ b/Source/MorseCode.ITask/_Root/AsyncMethodBuilderAttribute.cs
@@ -1,13 +1,15 @@
-namespace System.Runtime.CompilerServices
-{
- sealed class AsyncMethodBuilderAttribute : Attribute
- {
- public Type BuilderType { get; }
-
- public AsyncMethodBuilderAttribute(
- Type builderType)
- {
- BuilderType = builderType;
- }
- }
-}
+#if !NETSTANDARD2_1_OR_GREATER && !NETCOREAPP1_1_OR_GREATER
+namespace System.Runtime.CompilerServices
+{
+ sealed class AsyncMethodBuilderAttribute : Attribute
+ {
+ public Type BuilderType { get; }
+
+ public AsyncMethodBuilderAttribute(
+ Type builderType)
+ {
+ BuilderType = builderType;
+ }
+ }
+}
+#endif
diff --git a/Source/MorseCode.ITask/_Root/AwaiterInterfaceWrapper.cs b/Source/MorseCode.ITask/_Root/AwaiterInterfaceWrapper.cs
index 1c690c2..2aca00e 100644
--- a/Source/MorseCode.ITask/_Root/AwaiterInterfaceWrapper.cs
+++ b/Source/MorseCode.ITask/_Root/AwaiterInterfaceWrapper.cs
@@ -89,6 +89,9 @@ public void UnsafeOnCompleted(Action continuation)
/// The awaiter was not properly initialized.
/// The task was canceled.
/// The task completed in a Faulted state.
+#if NET6_0_OR_GREATER
+ [System.Diagnostics.StackTraceHidden]
+#endif
public void GetResult()
{
this.awaiter.GetResult();
diff --git a/Source/MorseCode.ITask/_Root/AwaiterInterfaceWrapper{TResult}.cs b/Source/MorseCode.ITask/_Root/AwaiterInterfaceWrapper{TResult}.cs
index 29a0257..8975359 100644
--- a/Source/MorseCode.ITask/_Root/AwaiterInterfaceWrapper{TResult}.cs
+++ b/Source/MorseCode.ITask/_Root/AwaiterInterfaceWrapper{TResult}.cs
@@ -93,6 +93,9 @@ public void UnsafeOnCompleted(Action continuation)
/// The awaiter was not properly initialized.
/// The task was canceled.
/// The task completed in a Faulted state.
+#if NET6_0_OR_GREATER
+ [System.Diagnostics.StackTraceHidden]
+#endif
public TResult GetResult()
{
return this.awaiter.GetResult();
diff --git a/Source/MorseCode.ITask/_Root/ConfiguredTaskAwaiterWrapper.cs b/Source/MorseCode.ITask/_Root/ConfiguredTaskAwaiterWrapper.cs
index a678d04..e84267e 100644
--- a/Source/MorseCode.ITask/_Root/ConfiguredTaskAwaiterWrapper.cs
+++ b/Source/MorseCode.ITask/_Root/ConfiguredTaskAwaiterWrapper.cs
@@ -62,6 +62,9 @@ void ICriticalNotifyCompletion.UnsafeOnCompleted(Action continuation)
this.taskAwaiter.UnsafeOnCompleted(continuation);
}
+#if NET6_0_OR_GREATER
+ [System.Diagnostics.StackTraceHidden]
+#endif
void IAwaiter.GetResult()
{
this.taskAwaiter.GetResult();
diff --git a/Source/MorseCode.ITask/_Root/ConfiguredTaskAwaiterWrapper{TResult}.cs b/Source/MorseCode.ITask/_Root/ConfiguredTaskAwaiterWrapper{TResult}.cs
index 2c48451..56b7b03 100644
--- a/Source/MorseCode.ITask/_Root/ConfiguredTaskAwaiterWrapper{TResult}.cs
+++ b/Source/MorseCode.ITask/_Root/ConfiguredTaskAwaiterWrapper{TResult}.cs
@@ -62,6 +62,9 @@ void ICriticalNotifyCompletion.UnsafeOnCompleted(Action continuation)
this.taskAwaiter.UnsafeOnCompleted(continuation);
}
+#if NET6_0_OR_GREATER
+ [System.Diagnostics.StackTraceHidden]
+#endif
TResult IAwaiter.GetResult()
{
return this.taskAwaiter.GetResult();
diff --git a/Source/MorseCode.ITask/_Root/TaskAwaiterWrapper.cs b/Source/MorseCode.ITask/_Root/TaskAwaiterWrapper.cs
index 9a5d6a0..7322033 100644
--- a/Source/MorseCode.ITask/_Root/TaskAwaiterWrapper.cs
+++ b/Source/MorseCode.ITask/_Root/TaskAwaiterWrapper.cs
@@ -62,6 +62,9 @@ void ICriticalNotifyCompletion.UnsafeOnCompleted(Action continuation)
this.taskAwaiter.UnsafeOnCompleted(continuation);
}
+#if NET6_0_OR_GREATER
+ [System.Diagnostics.StackTraceHidden]
+#endif
void IAwaiter.GetResult()
{
this.taskAwaiter.GetResult();
diff --git a/Source/MorseCode.ITask/_Root/TaskAwaiterWrapper{TResult}.cs b/Source/MorseCode.ITask/_Root/TaskAwaiterWrapper{TResult}.cs
index 508bef2..d8441c0 100644
--- a/Source/MorseCode.ITask/_Root/TaskAwaiterWrapper{TResult}.cs
+++ b/Source/MorseCode.ITask/_Root/TaskAwaiterWrapper{TResult}.cs
@@ -62,6 +62,9 @@ void ICriticalNotifyCompletion.UnsafeOnCompleted(Action continuation)
this.taskAwaiter.UnsafeOnCompleted(continuation);
}
+#if NET6_0_OR_GREATER
+ [System.Diagnostics.StackTraceHidden]
+#endif
TResult IAwaiter.GetResult()
{
return this.taskAwaiter.GetResult();
diff --git a/Source/MorseCode.ITask/_Root/TaskInterfaceAsyncMethodBuilder.cs b/Source/MorseCode.ITask/_Root/TaskInterfaceAsyncMethodBuilder.cs
index abe7dc2..72c6e01 100644
--- a/Source/MorseCode.ITask/_Root/TaskInterfaceAsyncMethodBuilder.cs
+++ b/Source/MorseCode.ITask/_Root/TaskInterfaceAsyncMethodBuilder.cs
@@ -1,91 +1,93 @@
-using System;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-namespace MorseCode.ITask.CompilerServices
-{
- ///
- /// Runtime helper for async methods returning .
- ///
- [StructLayout(LayoutKind.Auto)]
- public struct TaskInterfaceAsyncMethodBuilder
- {
- ///
- /// Delegate everything to the official method builder
- /// since we just use
- /// in the end.
- ///
- ///
- ///
- /// This must not be marked readonly because it is mutable. If marked
- /// readonly, first await silently freezes everything.
- ///
- ///
- AsyncTaskMethodBuilder builder;
-
- ///
- /// Used by the compiler to generate the return value for the async method.
- ///
- public ITask Task => builder.Task.AsITask();
-
- TaskInterfaceAsyncMethodBuilder(AsyncTaskMethodBuilder builder) : this()
- {
- this.builder = builder;
- }
-
-
-
- ///
- /// Part of async method builder contract: create a builder.
- ///
- public static TaskInterfaceAsyncMethodBuilder Create()
- => new TaskInterfaceAsyncMethodBuilder(
- AsyncTaskMethodBuilder.Create());
-
- ///
- /// Part of async method builder contract: set exception.
- ///
- public void SetException(Exception ex) => builder.SetException(ex);
-
- ///
- /// Part of async method builder contract: set RanToCompletion.
- ///
- public void SetResult() => builder.SetResult();
-
- ///
- /// Part of async method builder contract: set the state machine to use
- /// if the method ends up running asynchronously.
- ///
- public void SetStateMachine(IAsyncStateMachine stateMachine) => builder.SetStateMachine(stateMachine);
-
- ///
- /// Part of async method builder contract: initialize and start running
- /// the state machine.
- ///
- public void Start(ref TStateMachine stateMachine)
- where TStateMachine : IAsyncStateMachine
- => builder.Start(ref stateMachine);
-
- ///
- /// Part of async method builder contract: called when an awaited operation
- /// is pending completion to schedule a continuation.
- ///
- public void AwaitOnCompleted(
- ref TAwaiter awaiter,
- ref TStateMachine stateMachine)
- where TAwaiter : INotifyCompletion
- where TStateMachine : IAsyncStateMachine
- => builder.AwaitOnCompleted(ref awaiter, ref stateMachine);
-
- ///
- /// Part of async method builder contract: called when an awaited operation
- /// is pending completion to schedule a continuation.
- ///
- public void AwaitUnsafeOnCompleted(
- ref TAwaiter awaiter,
- ref TStateMachine stateMachine)
- where TAwaiter : ICriticalNotifyCompletion
- where TStateMachine : IAsyncStateMachine
- => builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine);
- }
-}
+using System;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+namespace MorseCode.ITask.CompilerServices
+{
+ ///
+ /// Runtime helper for async methods returning .
+ ///
+ [StructLayout(LayoutKind.Auto)]
+ public struct TaskInterfaceAsyncMethodBuilder
+ {
+ ///
+ /// Delegate everything to the official method builder
+ /// since we just use
+ /// in the end.
+ ///
+ ///
+ ///
+ /// This must not be marked readonly because it is mutable. If marked
+ /// readonly, first await silently freezes everything.
+ ///
+ ///
+ private AsyncTaskMethodBuilder builder;
+
+ ///
+ /// Used by the compiler to generate the return value for the async method.
+ ///
+ public ITask Task => builder.Task.AsITask();
+
+ private TaskInterfaceAsyncMethodBuilder(AsyncTaskMethodBuilder builder) : this()
+ {
+ this.builder = builder;
+ }
+
+ ///
+ /// Part of async method builder contract: create a builder.
+ ///
+ public static TaskInterfaceAsyncMethodBuilder Create()
+ => new TaskInterfaceAsyncMethodBuilder(
+ AsyncTaskMethodBuilder.Create());
+
+ ///
+ /// Part of async method builder contract: set exception.
+ ///
+ public void SetException(Exception ex) => builder.SetException(ex);
+
+ ///
+ /// Part of async method builder contract: set RanToCompletion.
+ ///
+ public void SetResult() => builder.SetResult();
+
+ ///
+ /// Part of async method builder contract: set the state machine to use
+ /// if the method ends up running asynchronously.
+ ///
+ public void SetStateMachine(IAsyncStateMachine stateMachine) => builder.SetStateMachine(stateMachine);
+
+ ///
+ /// Part of async method builder contract: initialize and start running
+ /// the state machine.
+ ///
+ [DebuggerStepThrough]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void Start(ref TStateMachine stateMachine)
+ where TStateMachine : IAsyncStateMachine
+ => builder.Start(ref stateMachine);
+
+ ///
+ /// Part of async method builder contract: called when an awaited operation
+ /// is pending completion to schedule a continuation.
+ ///
+ public void AwaitOnCompleted(
+ ref TAwaiter awaiter,
+ ref TStateMachine stateMachine)
+ where TAwaiter : INotifyCompletion
+ where TStateMachine : IAsyncStateMachine
+ => builder.AwaitOnCompleted(ref awaiter, ref stateMachine);
+
+ ///
+ /// Part of async method builder contract: called when an awaited operation
+ /// is pending completion to schedule a continuation.
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void AwaitUnsafeOnCompleted(
+ ref TAwaiter awaiter,
+ ref TStateMachine stateMachine)
+ where TAwaiter : ICriticalNotifyCompletion
+ where TStateMachine : IAsyncStateMachine
+ => builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine);
+ }
+}
diff --git a/Source/MorseCode.ITask/_Root/TaskInterfaceAsyncMethodBuilder{TResult}.cs b/Source/MorseCode.ITask/_Root/TaskInterfaceAsyncMethodBuilder{TResult}.cs
index 74e5c4e..3871000 100644
--- a/Source/MorseCode.ITask/_Root/TaskInterfaceAsyncMethodBuilder{TResult}.cs
+++ b/Source/MorseCode.ITask/_Root/TaskInterfaceAsyncMethodBuilder{TResult}.cs
@@ -1,91 +1,93 @@
-using System;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-namespace MorseCode.ITask.CompilerServices
-{
- ///
- /// Runtime helper for async methods returning .
- ///
- [StructLayout(LayoutKind.Auto)]
- public struct TaskInterfaceAsyncMethodBuilder
- {
- ///
- /// Delegate everything to the official method builder
- /// since we just use
- /// in the end.
- ///
- ///
- ///
- /// This must not be marked readonly because it is mutable. If marked
- /// readonly, first await silently freezes everything.
- ///
- ///
- AsyncTaskMethodBuilder builder;
-
- ///
- /// Used by the compiler to generate the return value for the async method.
- ///
- public ITask Task => builder.Task.AsITask();
-
- TaskInterfaceAsyncMethodBuilder(AsyncTaskMethodBuilder builder) : this()
- {
- this.builder = builder;
- }
-
-
-
- ///
- /// Part of async method builder contract: create a builder.
- ///
- public static TaskInterfaceAsyncMethodBuilder Create()
- => new TaskInterfaceAsyncMethodBuilder(
- AsyncTaskMethodBuilder.Create());
-
- ///
- /// Part of async method builder contract: set exception.
- ///
- public void SetException(Exception ex) => builder.SetException(ex);
-
- ///
- /// Part of async method builder contract: set RanToCompletion.
- ///
- public void SetResult(TResult result) => builder.SetResult(result);
-
- ///
- /// Part of async method builder contract: set the state machine to use
- /// if the method ends up running asynchronously.
- ///
- public void SetStateMachine(IAsyncStateMachine stateMachine) => builder.SetStateMachine(stateMachine);
-
- ///
- /// Part of async method builder contract: initialize and start running
- /// the state machine.
- ///
- public void Start(ref TStateMachine stateMachine)
- where TStateMachine : IAsyncStateMachine
- => builder.Start(ref stateMachine);
-
- ///
- /// Part of async method builder contract: called when an awaited operation
- /// is pending completion to schedule a continuation.
- ///
- public void AwaitOnCompleted(
- ref TAwaiter awaiter,
- ref TStateMachine stateMachine)
- where TAwaiter : INotifyCompletion
- where TStateMachine : IAsyncStateMachine
- => builder.AwaitOnCompleted(ref awaiter, ref stateMachine);
-
- ///
- /// Part of async method builder contract: called when an awaited operation
- /// is pending completion to schedule a continuation.
- ///
- public void AwaitUnsafeOnCompleted(
- ref TAwaiter awaiter,
- ref TStateMachine stateMachine)
- where TAwaiter : ICriticalNotifyCompletion
- where TStateMachine : IAsyncStateMachine
- => builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine);
- }
-}
+using System;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+namespace MorseCode.ITask.CompilerServices
+{
+ ///
+ /// Runtime helper for async methods returning .
+ ///
+ [StructLayout(LayoutKind.Auto)]
+ public struct TaskInterfaceAsyncMethodBuilder
+ {
+ ///
+ /// Delegate everything to the official method builder
+ /// since we just use
+ /// in the end.
+ ///
+ ///
+ ///
+ /// This must not be marked readonly because it is mutable. If marked
+ /// readonly, first await silently freezes everything.
+ ///
+ ///
+ private AsyncTaskMethodBuilder builder;
+
+ ///
+ /// Used by the compiler to generate the return value for the async method.
+ ///
+ public ITask Task => builder.Task.AsITask();
+
+ private TaskInterfaceAsyncMethodBuilder(AsyncTaskMethodBuilder builder) : this()
+ {
+ this.builder = builder;
+ }
+
+ ///
+ /// Part of async method builder contract: create a builder.
+ ///
+ public static TaskInterfaceAsyncMethodBuilder Create()
+ => new TaskInterfaceAsyncMethodBuilder(
+ AsyncTaskMethodBuilder.Create());
+
+ ///
+ /// Part of async method builder contract: set exception.
+ ///
+ public void SetException(Exception ex) => builder.SetException(ex);
+
+ ///
+ /// Part of async method builder contract: set RanToCompletion.
+ ///
+ public void SetResult(TResult result) => builder.SetResult(result);
+
+ ///
+ /// Part of async method builder contract: set the state machine to use
+ /// if the method ends up running asynchronously.
+ ///
+ public void SetStateMachine(IAsyncStateMachine stateMachine) => builder.SetStateMachine(stateMachine);
+
+ ///
+ /// Part of async method builder contract: initialize and start running
+ /// the state machine.
+ ///
+ [DebuggerStepThrough]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void Start(ref TStateMachine stateMachine)
+ where TStateMachine : IAsyncStateMachine
+ => builder.Start(ref stateMachine);
+
+ ///
+ /// Part of async method builder contract: called when an awaited operation
+ /// is pending completion to schedule a continuation.
+ ///
+ public void AwaitOnCompleted(
+ ref TAwaiter awaiter,
+ ref TStateMachine stateMachine)
+ where TAwaiter : INotifyCompletion
+ where TStateMachine : IAsyncStateMachine
+ => builder.AwaitOnCompleted(ref awaiter, ref stateMachine);
+
+ ///
+ /// Part of async method builder contract: called when an awaited operation
+ /// is pending completion to schedule a continuation.
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void AwaitUnsafeOnCompleted(
+ ref TAwaiter awaiter,
+ ref TStateMachine stateMachine)
+ where TAwaiter : ICriticalNotifyCompletion
+ where TStateMachine : IAsyncStateMachine
+ => builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine);
+ }
+}
diff --git a/Source/MorseCode.ITask/_Root/_Root.csproj b/Source/MorseCode.ITask/_Root/_Root.csproj
index 409b6de..43a52fe 100644
--- a/Source/MorseCode.ITask/_Root/_Root.csproj
+++ b/Source/MorseCode.ITask/_Root/_Root.csproj
@@ -1,7 +1,7 @@
- netstandard1.0;netstandard2.0;net45
+ netstandard1.0;netstandard2.0;netstandard2.1;net45;net6.0
2.0.0
MorseCode Software
An awaitable covariant ITask interface which may be used in place of the built-in Task class.