In my winform programme I use Postsharp interceptor class on each control event to avoid try/catch block repetition.
The custom postsharp method:
[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;
}
}
}
Usage this the attributs:
[OnErrorShowMessageBox]
private void txtComments_TextChanged(object sender, EventArgs e)
{
//blabla
}
This works like a charm BUT know I would like to use async on the event. So txtComments_textChanged become :
[OnErrorShowMessageBox]
private async void txtComments_TextChanged(object sender, EventArgs e)
{
await //blabla
}
And here comes the problem. Try/catch bloc in the interceptor method don't catch anything when is async... How can I do ? thanks
First of all, if you need an aspect to handle exceptions, then it's usually better to implement it as OnMethodBoundaryAspect or OnExceptionAspect. In your OnException
method you can set args.FlowBehavior
to FlowBehavior.Return or FlowBehavior.Continue to prevent the exception from being thrown.
In addition to providing better performance, these aspects can also be applied to async methods by setting the ApplyToStateMachine
property to true
. There is a caveat though - with state machines it's not possible to change the exception flow behavior. You can still process the exception, but you cannot prevent it from being thrown.
Update. Starting with PostSharp 5.0, it is possible to change the flow behavior of async methods.
[Serializable]
public class MyAspect : OnExceptionAspect
{
public MyAspect()
{
this.ApplyToStateMachine = true;
}
public override void OnException(MethodExecutionArgs args)
{
Console.WriteLine("OnException({0});", args.Exception.Message);
}
}
If the aspect is not going to be applied to async methods then you can show the message box and ignore the exception, as shown in the following example
Update. Starting with PostSharp 5.0, the following example also works with async methods.
[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;
}
}