【问题标题】:Handling exceptions in .NET (GUI) event functions without excessive boilerplate?在没有过多样板的情况下处理 .NET (GUI) 事件函数中的异常?
【发布时间】:2011-09-10 17:30:12
【问题描述】:

注意:我不经常进行 .NET 编程。通常我做原生/MFC,所以我有点迷失如何在 C# 的上下文中正确地做到这一点。

我们在 native MFC 应用程序的上下文中显示 .NET 控件。这意味着 GUI 线程是调用 .NET 控件的 WndProc 的本机线程。 (嗯,至少据我所知。)

显然,我们确实想从我们的 (GUI) 事件处理程序中抛出异常,因为调用堆栈中没有适当的处理程序可以捕获它们。

据我所知,AppDomain / UnhandledExceptionEventHandler 的解决方案在本机 MFC 应用程序中没有意义。 (如果我错了,请纠正我。)

回到问题:如何避免必须向 C# 控制代码的每个事件处理程序添加 try/catch 块?是否有某个地方(可能是 System.Forms...Control.WndProc?)我可以捕获所有 .NET 异常并向用户显示错误对话框?

【问题讨论】:

  • Martin 时不时会出现像您这样的问题,实际上最好的办法是一一处理这些异常,因为根据您所处的位置,您会更好地了解如何处理它。这不仅是关于记录或显示消息框,更是关于以不同方式对不同情况做出反应。

标签: .net user-interface exception mfc


【解决方案1】:

您可以使用函数式方法减少样板代码。写一个这样的函数:

public class Util
{
    public static void SafeCall(Action handler)
    {
      try
      {
           handler();
      }
      catch(Exception ex)
      {
         // process ex here
      }
}

并在每个 GUI 事件处理程序中重用它:

void MyEvent(object sender, EventArgs e)
{
    Util.SafeCall(()=>NameOfYourHandlerMethod(sender,e));
};

void MyEvent(object sender, EventArgs e)
{
    Util.SafeCall(
    delegate
    {
      // enter code here
    });
};

这可能需要一些额外的工作才能以您想要的方式获取 sender/EventArgs 参数,但您应该明白这一点。

【讨论】:

  • 不错的解决方案,但在 SafeCall 中,您无法访问原始方法参数,并且您在另一个方法中,因此反射和其他与堆栈跟踪相关的事情是不同的。
  • @Davide Piras:堆栈跟踪不应该成为问题,您只会获得一个额外的级别。可以根据需要传递参数(正如我在帖子中所写的那样)。最大的不同是您不再在 GUI 类中,因此如果您进行一些通用错误处理,此解决方案最适用。我想这就是 OP 的想法,因为他的目标是减少不必要的代码重复。
猜你喜欢
  • 1970-01-01
  • 2021-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多