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;
}
}