C#基于事件封装捕获异常从而减少try catch
一般情况下,我们在开发winform程序的时候,按钮点击事件等这些异常的处理都是手动写try/catch实现,就如下面的代码:
private void BtnCalculate_Click(object? sender, EventArgs e)
{
try
{
//业务逻辑
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
这样会在程序中到处都会有一堆重复的代码,如何能对这些异常进行统一的管理,这里看到老A提供的一个处理思路很好。
对EventHandler进行封装
根本目的就是让执行事件处理程序的时候在外面人为地套一个Try/Catch,并对捕获的异常进行相应的处理。从这个意义上讲,如果我们能够对EventHandler或者EventHandler<TEventArgs>进行相应的封装,就能实现我们需要的目的。
我们新建一个EventHandlerWrapper
的类,代码实现如下:
public class EventHandlerWrapper
{
public object Target { get; private set; }
public MethodInfo Method { get; private set; }
public EventHandler Hander { get; private set; }
public EventHandlerWrapper(EventHandler eventHandler)
{
if (null == eventHandler)
{
throw new ArgumentNullException("eventHandler");
}
this.Target = eventHandler.Target;
this.Method = eventHandler.Method;
this.Hander += Invoke;
}
public static implicit operator EventHandler(EventHandlerWrapper eventHandlerWrapper)
{
return eventHandlerWrapper.Hander;
}
private void Invoke(object sender, EventArgs args)
{
if (null != Form.ActiveForm)
{
Form.ActiveForm.Cursor = Cursors.WaitCursor;
}
try
{
this.Method.Invoke(this.Target, new object[] { sender, args });
}
catch (TargetInvocationException ex)
{
StringBuilder message = new StringBuilder();
message.AppendLine(string.Format("Message: {0}", ex.InnerException.Message));
message.AppendLine(string.Format("Exception Type: {0}", ex.InnerException.GetType().AssemblyQualifiedName));
message.AppendLine(string.Format("Stack Trace: {0}", ex.InnerException.StackTrace));
EventLog.WriteEntry("Application", message.ToString(), EventLogEntryType.Error, 0);
MessageBox.Show(ex.InnerException.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
if (null != Form.ActiveForm)
{
Form.ActiveForm.Cursor = Cursors.Default;
}
}
}
}
EventHandlerWrapper通过EventHandler对象创建,并将EventHandler的Target和Method赋值给EventHandlerWrapper的同名属性。此外,EventHandlerWrapper得Invoke方法中,将对Method的调用放在一个Try/Catch中,并对捕获的异常进行简单的处理:记录到EventLog中在通过MessageBox将相关异常信息显示出来。而EventHandlerWrapper的Handler属性就是对该Invoke方法的直接反映。最后定义了一个隐式类型转换将EventHandlerWrapper直接转换成EventHandler。转化后返回的就是反映Invoke方法的Handler属性。
写一个示例程序,界面如下:
代码如下:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
//一般的事件调用
//btnCalculate.Click += BtnCalculate_Click;
//使用委托封装后的事件调用
btnCalculate.Click += new EventHandlerWrapper(BtnCalculate_Click);
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void BtnCalculate_Click(object? sender, EventArgs e)
{
double num1 = double.Parse(txtNum1.Text);
double num2 = double.Parse(txtNum2.Text);
double result = num1 / num2;
txtNum3.Text = result.ToString();
}
}
一般的事件调用,我们需要手动处理try/catch,而使用封装后的
EventHandlerWrapper
我们并不需要去手动处理了。
本文内容参考https://www.cnblogs.com/artech/archive/2010/03/26/1697298.html