Hangs in custom AsyncTaskMethodBuilder. #71521
-
Hello! I'm starting to deep dive into async machinery in C#, and I've implemented a custom I don't understand why it hangs and where I made a mistake. Could someone highlight these points for me? Thank you! using System.Diagnostics;
using System.Runtime.CompilerServices;
await AwaitMethodCollection.TaskAsync(); //hang here
public static class AwaitMethodCollection
{
[AsyncMethodBuilder(typeof(CustomAsyncTaskMethodBuilder))]
public static async Task TaskAsync()
{
Console.WriteLine("TaskAsync");
await Task.Delay(100);
}
}
public readonly struct CustomAsyncTaskMethodBuilder
{
private readonly AsyncTaskMethodBuilder _orig;
public CustomAsyncTaskMethodBuilder()
{
_orig = new AsyncTaskMethodBuilder();
Console.WriteLine("Builder: .ctor");
}
public static CustomAsyncTaskMethodBuilder Create()
{
return new CustomAsyncTaskMethodBuilder();
}
public Task Task => _orig.Task;
public void SetResult()
{
_orig.SetResult();
Console.WriteLine("Builder: SetResult");
}
public void SetException(Exception exception)
{
_orig.SetException(exception);
Console.WriteLine("Builder: SetException");
}
public void AwaitOnCompleted<TAwaiter, TStateMachine>(
ref TAwaiter awaiter,
ref TStateMachine stateMachine)
where TAwaiter : INotifyCompletion
where TStateMachine : IAsyncStateMachine
{
_orig.AwaitOnCompleted(
ref awaiter,
ref stateMachine
);
}
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(
ref TAwaiter awaiter,
ref TStateMachine stateMachine)
where TAwaiter : ICriticalNotifyCompletion
where TStateMachine : IAsyncStateMachine
{
_orig.AwaitUnsafeOnCompleted(
ref awaiter,
ref stateMachine
);
}
public void Start<TStateMachine>(ref TStateMachine stateMachine)
where TStateMachine : IAsyncStateMachine
{
_orig.Start(ref stateMachine);
}
public void SetStateMachine(IAsyncStateMachine stateMachine)
{
_orig.SetStateMachine(stateMachine);
}
} its output:
|
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
You should remove |
Beta Was this translation helpful? Give feedback.
You should remove
readonly
from_orig
declaration.AsyncTaskMethodBuilder
is a mutable struct so the compiler makes a defensive copy of_orig
before calling its method to make sure the field will not be changed. and so in the end_orig.Task
will always return different task that will newer finish