Brackets
Brackets

Reputation: 572

add event listener in extension method

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

Answers (1)

Servy
Servy

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

Related Questions