Postsharp AOP MethodInterception Аспект с асинхронным

В моей программе winform я использую класс перехватчика Postsharp для каждого управляющего события, чтобы избежать повторения блоков try/catch.

Пользовательский метод postharp:

[Serializable]
public class OnErrorShowMessageBox : MethodInterceptionAspect
{
    public override void OnInvoke(MethodInterceptionArgs args)
    {
        try
        {               
            args.Proceed();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Error);
            args.ReturnValue = null;
        }
    }
}

Использование этого атрибута:

    [OnErrorShowMessageBox]
    private void txtComments_TextChanged(object sender, EventArgs e)
    {
       //blabla
    }

Это работает как очарование, НО знаю, что я хотел бы использовать async на событии. Так что txtComments_textChanged становится:

    [OnErrorShowMessageBox]
    private async void txtComments_TextChanged(object sender, EventArgs e)
    {
        await //blabla
    }

И тут возникает проблема. Блок try/catch в методе перехватчика ничего не перехватывает, когда выполняется асинхронность... Как я могу это сделать? Спасибо

1 ответ

Решение

Прежде всего, если вам нужен аспект для обработки исключений, то обычно лучше реализовать его как OnMethodBoundaryAspect или OnExceptionAspect. В вашем OnException метод, который вы можете установить args.FlowBehavior для FlowBehavior.Return или FlowBehavior.Continue, чтобы исключение было выброшено.

Помимо обеспечения лучшей производительности, эти аспекты также могут быть применены к асинхронным методам путем установки ApplyToStateMachine собственность на true, Однако есть предостережение - с помощью конечных автоматов невозможно изменить поведение потока исключений. Вы все еще можете обработать исключение, но не можете предотвратить его выброс.

Обновить. Начиная с PostSharp 5.0, можно изменить поведение потока асинхронных методов.

[Serializable]
public class MyAspect : OnExceptionAspect
{
    public MyAspect()
    {
        this.ApplyToStateMachine = true;
    }

    public override void OnException(MethodExecutionArgs args)
    {
        Console.WriteLine("OnException({0});", args.Exception.Message);
    }
}

Если аспект не будет применяться к асинхронным методам, вы можете отобразить окно сообщения и проигнорировать исключение, как показано в следующем примере.

Обновить. Начиная с PostSharp 5.0, следующий пример также работает с асинхронными методами.

[Serializable]
public class MyAspect : OnExceptionAspect
{
    public override void OnException(MethodExecutionArgs args)
    {
        MessageBox.Show(ex.Message, "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Error);
        args.ReturnValue = null;
        args.FlowBehavior = FlowBehavior.Return;
    }
}
Другие вопросы по тегам