добавить прослушиватель событий в методе расширения - PullRequest
0 голосов
/ 24 марта 2020

В моем основном классе у меня есть такое событие

private event System.Action OnActionFinished;

И зная, что await вызывает метод GetAwaiter (), у меня есть метод расширения System.Action: `

public static TaskAwaiter<object> GetAwaiter(this Action action)
{
    TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();
    action += () => tcs.SetResult(null);
    return tcs.Task.GetAwaiter();
}

in чтобы иметь возможность писать await OnActionFinished; в методе async.

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 вызывается в конце методов Walk, Jump и Shoot.

Почему это не работает

1 Ответ

1 голос
/ 24 марта 2020

Action является неизменным типом. Вы не изменяете это действие таким образом, чтобы оно вызывало другое поведение при вызове, вы создаете новое действие (с которым потом ничего не делаете), которое завершает ваш TCS.

Для общей возможности создания Task на основе любого произвольного события довольно сложно, и сделать это с полной безопасностью типов невозможно. Вы можете увидеть некоторые трудности с этим здесь . Теперь создать Task на основе определенного события для определенного объекта, конечно, это легко (опять же, см. Ранее связанный вопрос).

В основном это связано с тем, что сам язык C# разоблачает события, просто не позволяющие этого.

...