带有异步的 Postsharp AOP 方法拦截方面
Postsharp AOP MethodInterception Aspect with async
在我的 winform 程序中,我在每个控制事件上使用 Postsharp 拦截器 class 以避免 try/catch 块重复。
自定义postsharp方法:
[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
}
这很有用,但我知道我想在事件中使用异步。所以 txtComments_textChanged 变成:
[OnErrorShowMessageBox]
private async void txtComments_TextChanged(object sender, EventArgs e)
{
await //blabla
}
问题来了。 Try/catch 拦截器方法中的 bloc 在异步时不捕获任何内容...
我能怎么做 ?
谢谢
首先,如果你需要一个方面来处理异常,那么通常最好将它实现为OnMethodBoundaryAspect or OnExceptionAspect. In your OnException
method you can set args.FlowBehavior
to FlowBehavior.Return or FlowBehavior.Continue以防止抛出异常。
除了提供更好的性能外,这些方面还可以通过将 ApplyToStateMachine
属性 设置为 true
来 applied to async methods。但有一个警告 - 使用状态机无法更改异常流行为。您仍然可以处理异常,但无法阻止它被抛出。
更新。 从 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;
}
}
在我的 winform 程序中,我在每个控制事件上使用 Postsharp 拦截器 class 以避免 try/catch 块重复。
自定义postsharp方法:
[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
}
这很有用,但我知道我想在事件中使用异步。所以 txtComments_textChanged 变成:
[OnErrorShowMessageBox]
private async void txtComments_TextChanged(object sender, EventArgs e)
{
await //blabla
}
问题来了。 Try/catch 拦截器方法中的 bloc 在异步时不捕获任何内容... 我能怎么做 ? 谢谢
首先,如果你需要一个方面来处理异常,那么通常最好将它实现为OnMethodBoundaryAspect or OnExceptionAspect. In your OnException
method you can set args.FlowBehavior
to FlowBehavior.Return or FlowBehavior.Continue以防止抛出异常。
除了提供更好的性能外,这些方面还可以通过将 ApplyToStateMachine
属性 设置为 true
来 applied to async methods。但有一个警告 - 使用状态机无法更改异常流行为。您仍然可以处理异常,但无法阻止它被抛出。
更新。 从 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;
}
}