【问题标题】:top-level exception handling with event handlers in c#在 C# 中使用事件处理程序进行顶级异常处理
【发布时间】:2010-10-25 20:09:53
【问题描述】:

我目前正在问自己一些关于异常处理和事件处理程序的问题,希望你们中的一些人能给我一些帮助。

我将开始解释我想在我的 c# 应用程序中实现什么:

我有一个顶级方法(我们称之为 main 方法)。此方法调用一个异步方法(称为 connect),该方法连接到 FTP 服务器。

这个连接关联一个EventHandler对象,连接成功时会调用一个“回调”方法。

我想处理可以在整个过程中启动的异常。所以我想在顶级方法中抓住它。它适用于由 connect 方法(在顶级方法内部调用)启动的异常。 但是,它不适用于“回调”方法内部调用的异常:顶级方法没有捕获它们并且执行失败。

我该怎么做才能让顶级方法捕获这些异常?我不想在回调中处理这些异常。

【问题讨论】:

    标签: c# exception events asynchronous


    【解决方案1】:

    处理这个顶级异常处理问题的更方便的方法是使用委托。

    这些 c# 委托允许以异步方式调用方法。委托还允许顶级异常处理。实际上,委托内部抛出的异常会在原始线程上重新抛出。

    我不知道为什么我以前没有考虑过代表。 我希望它会有所帮助。

    查看这些关于委托的精彩文章:

    Article 1

    Article 2

    【讨论】:

    • 但是紧凑框架不支持异步委托... :(
    【解决方案2】:

    感谢您的回答。

    看来使用BackgroundWorker可以解决这个问题。

    我没有尝试,因为我选择避免这种实施负担。所以我取消了我的异步调用,让我的应用程序同步运行。

    对于使用 Compact Framework 而不是完整的 .NET Framework 的人的一个提示: BackgroundWorker 在 CF 中不可用,但 OpenNETCF 提供了类似的解决方案(请参阅 Smart Device Framework 中的 BackgroundWorker 类)。

    【讨论】:

      【解决方案3】:

      考虑以下代码片段,用于将所有代码包装在全局异常处理程序中:

      namespace MyClient
      {
        class Program
        {
          static void Main(string[] args)
          {
            try
            {
              bool isSuccess = SubMain(string[] args);
            }
            catch (Exception e)
            {
              HandleExceptionGracefully(e);
            }
          }
          static bool SubMain(string[] agrs)
          {
             // Do something
          }
          static void HandleExceptionGracefully(Exception e)
          {
             // Display/Send the exception in a graceful manner to the user/admin.
          }
        }
      }
      

      另外,别忘了让你的错误处理user-friendly.

      【讨论】:

        【解决方案4】:

        看看 Backgroundworker 是如何处理这个问题的:异常被传播到 Completed 事件处理程序。

        我假设您有某种形式的 State 对象传递给委托/从委托传递,您可以在其中添加这样的属性。而且您必须在最外层范围内捕获线程中的所有异常。但“处理”只是意味着传递它。

        RunWorkerCompleted 事件有一个标准模式,请参阅this MSDN page。

        【讨论】:

          【解决方案5】:

          Application 类中有一个名为ThreadException 的事件处理程序。每当在当前调用堆栈中的任何地方抛出一个未捕获的异常时,都会触发此事件。


          已编辑:

          抱歉,我误读了这个问题 - 我没有意识到您示例中的“main”方法不是实际的 main 方法。在这种情况下,您可能希望在回调中捕获异常,但不对其进行处理 - 只需将其作为事件参数的一部分传回主方法。

          Winforms 中的 BackgroundWorker 做了类似的事情。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-01-29
            • 2012-09-02
            • 1970-01-01
            • 2013-01-07
            • 1970-01-01
            相关资源
            最近更新 更多