【问题标题】:WinForms Exception handlingWinForms 异常处理
【发布时间】:2025-12-07 14:25:02
【问题描述】:

我有一个从 db 填充数据集的方法,它看起来或多或少像这样:

private DataSet GetData(string query)
{
    try
    {
        //do some stuff to populate dataset
        return dataset;
    }
    catch (SqlException ex)
    {
        MessageBox.Show("There was a database error. Please contact administrator.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        LogExceptionToFile(ex); //to log whole exception stack trace, etc.
    }
    finally
    {
        //cleanup
    }
}

//calling methods:
GetData(query);
OtherMethod1(); //this method shows message box of success

当我有那段代码以防出现异常时,我得到了用户友好的消息框,然后调用 OtherMethod1() 并显示成功消息框。如果GetData() 中有错误,我想停止。当我在我的消息框之后将throw; 添加到这个catch 块时,显示了另一个消息框,而不是引发了未处理的异常。如果我提供了友好的消息,我想避免显示第二个消息框。

【问题讨论】:

  • 如果您在GetData() 方法中添加throw,则需要在该方法周围使用try/catch 来实际捕获异常。否则,您将需要一些变量来跟踪GetData 中的成功/失败,然后根据是否有异常采取相应的行动。

标签: c# error-handling exception-handling


【解决方案1】:

可以返回一个表示成功的值:

private bool TryGetData(string query, out DataSet dataSet)
{
    try
    {
        dataSet = ...;
        //do some stuff to populate dataset
        return true;
    }
    catch (SqlException ex)
    {
        MessageBox.Show("There was a database error. Please contact administrator.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        LogExceptionToFile(ex); //to log whole exception stack trace, etc.
        return false;
    }
    finally
    {
        //cleanup
    }
}

//calling methods:
DataSet ds;
if (TryGetData(query, out ds))
{
   OtherMethod1(); 
}
else
{
   //error
}

【讨论】:

    【解决方案2】:

    如果我正确理解了您的困境,您可以像这样重新抛出和处理(当前未处理的)异常:

    private DataSet GetData(string query)
    {
        try
        {
            //do some stuff to populate dataset
            return dataset;
        }
        catch (SqlException ex)
        {
            MessageBox.Show("There was a database error. Please contact administrator.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            LogExceptionToFile(ex); //to log whole exception stack trace, etc.
    
            throw;
        }
        finally
        {
            //cleanup
        }
    }
    
    
    //calling methods:
    try
    {
        GetData(query);
        OtherMethod1(); //this method shows message box of success
    }
    catch(Exception ex)
    {
        //Do whatever you need to do here, if anything.
    }
    

    现在,这当然不是唯一的方法,我只是向您展示如何做听起来像是您正在尝试的事情。其中一些其他答案也很好,可能更适合您的特定情况。

    【讨论】:

      【解决方案3】:

      我会说你可以使用回调。

      Here's a link on returning multiple values

      让您的GetData() 方法使用回调返回多个值。然后,您可以从callBack 的值中设置一个success 布尔值,该值由GetData() 方法给出。

      然后在您的调用代码中,仅当 success 布尔值为 true 时才运行您的 OtherMethod()

      您甚至可以将ex 异常作为回调的一部分返回,并使用一段代码来显示一个对话框;是成功还是失败,如果是,则在其中显示异常。

      例子:

      private DataSet GetData(string query, Action<bool> callBack)
      {
          bool successful = false; // This will be returned in the callback.
          DataSet returnValue; // This will be the dataset stuff.
          try
          {
              //do some stuff to populate dataset
              returnValue = ???; // Populate your return value , but don't return yet;
              successful = true; // This will indicate success.
          }
          catch (SqlException ex)
          {
              MessageBox.Show("There was a database error. Please contact administrator.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
              LogExceptionToFile(ex); //to log whole exception stack trace, etc.
          }
          finally
          {
              //cleanup
      
              if (callBack != null) // Send the callback with the boolean of successful.
              {
                  callBack(successful);
              }
      
              return returnValue; // Now return your DataSet.
          }
      }
      
      bool success = false; // Use this to determine if GetData was successful.
      //calling methods:
      GetData(query, (s) => success = s);
      
      if (success)
      {
          OtherMethod1(); //this method shows message box of success
      }
      else
      {
          // Do something else, or show your failure message box.
      }
      

      这样更干净。

      希望这会有所帮助!

      【讨论】:

        【解决方案4】:

        如果出现错误,您可以简单地返回 null。 (尽管可能不鼓励使用 null,这取决于您与谁交谈或您的公司或项目中的编码指南可能是什么。)

        private DataSet GetData(string query)
        {
            try
            {
                //do some stuff to populate dataset
                return dataset;
            }
            catch (SqlException ex)
            {
                MessageBox.Show("There was a database error. Please contact administrator.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                LogExceptionToFile(ex); //to log whole exception stack trace, etc.
            }
            finally
            {
                //cleanup
            }
        
            return null;
        }
        
        //calling methods:
        var result = GetData(query);
        if (result != null) 
            OtherMethod1(); //this method shows message box of success
        

        【讨论】:

          【解决方案5】:

          您可以在GetData() 中添加throw;catch

          private DataSet GetData(string query)
          {
              try
              {
                  //do some stuff to populate dataset
                  return dataset;
              }
              catch (SqlException ex)
              {
                  MessageBox.Show("There was a database error. Please contact administrator.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                  LogExceptionToFile(ex); //to log whole exception stack trace, etc.
                  throw;
              }
              finally
              {
                  //cleanup
              }
          }
          

          然后这样做:

          try
          {
            GetData(query);
            OtherMethod1();
          }
          catch (Exception ex)
          {
            // do something to ex if needed
          }
          

          这样您就不会得到第二个消息框,并且可以在需要时再次处理异常。

          【讨论】:

            最近更新 更多