Reputation: 572
In my main class, I have such event
private event System.Action OnActionFinished;
And knowing that await calls GetAwaiter() method, I have System.Action extension method: `
public static TaskAwaiter<object> GetAwaiter(this Action action)
{
TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();
action += () => tcs.SetResult(null);
return tcs.Task.GetAwaiter();
}
in order to be able to write await OnActionFinished;
in async
method.
public async Task ExecuteTurns(Queue<TurnAction> turnActions)
{
foreach (TurnAction turn in turnActions)
{
Action<Vector2> TurnMethod = null;
switch (turn.TurnType)
{
case TurnType.Walk:
TurnMethod = Walk;
break;
case TurnType.Jump:
TurnMethod = Jump;
break;
case TurnType.Shoot:
TurnMethod = rangedWeapon.Shoot;
break;
}
Task.Run(async () => {
TurnMethod(turn.Direction);
});
await OnActionFinished;
}
}
OnActionFinished is invoked in the end of Walk, Jump, And Shoot methods.
Why does this not work?
Upvotes: 0
Views: 316
Reputation: 203821
Action
is an immutable type. You're not changing that action such that it performs different behavior when invoked, you're creating a new action (which you then do nothing with) that completes your TCS.
To generically be able to construct a Task
based on any arbitrary event is rather hard, and doing it with complete type safety is impossible. You can see some of the difficulties with doing that here. Now to create a Task
based on a particular event on a particular object, sure, that's easy (again, see the previously linked question).
This mostly stems from the feature that the C# language itself exposes around events simply not allowing for this.
Upvotes: 1