C# 异常导致的错误消息处理

C# 异常导致的错误消息处理,c#,winforms,try-catch,C#,Winforms,Try Catch,我有一个代码,可以在一个事件中重新启动一个服务,该事件也会执行其他功能 我在活动中尝试捕捉活动中的所有内容,如下所示: private void btnApply_Click(object sender, EventArgs e) { try { applyChangesAndCheckRestartService(); } catch (Exception ex)

我有一个代码,可以在一个事件中重新启动一个服务,该事件也会执行其他功能

我在活动中尝试捕捉活动中的所有内容,如下所示:

private void btnApply_Click(object sender, EventArgs e)
    {
        try
        {               
            applyChangesAndCheckRestartService();
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error loading page.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }

private void applyChangesAndCheckRestartService()
    {
        string svrPortNo = CommonCodeClass.getTagValue(CommonCodeClass.xml_SvrPortNoTag, CommonCodeClass.configLocation + CommonCodeClass.configXML);               

        if (!ApplyChangesForSettings())
        {                
            return;
        }

        if (svrPortNo != tbSvrPortNo.Text)
        {               
            CommonCodeClass.CheckToRestartService();
        }
    }
现在,如果在ApplyChangesForSettings()过程中出现错误,我将得到一个错误弹出窗口“错误加载页面”

如果CheckToRestartService()中有错误,我将由于try-catch而得到相同的错误

有没有更好的方法来处理这个问题

比如,我不介意加载ApplyChangesForSettings()页面时出错,但对于CheckToRestartService(),我希望看到类似“无法重新启动服务”的错误

如有任何建议,我们将不胜感激。 谢谢


处理这种情况的最快方法是在您的某个内部方法失败时引发异常,并在btnApply_单击中捕获消息

MessageBox.Show(ex.Message, "Error",  .....);
最正确的方法是创建自己的异常类型,并在方法内部,如果存在失败条件,则抛出自己的异常。例如,创建这样一个类

public class RestartServiceException : Exception
{
    public RestartServiceException(string message)
        : base(message)
    {
    }
    // You could also write other constructors with different parameters and use internal logic
    // to process your error message
}
然后,当CheckToRestartService方法中出现失败条件时,使用该类的实例

   if(fail == true)
       throw new RestartServiceException("The service could not be started because .....");

处理这种情况的最快方法是在您的某个内部方法失败时引发异常,并在btnApply_单击中捕获消息

MessageBox.Show(ex.Message, "Error",  .....);
最正确的方法是创建自己的异常类型,并在方法内部,如果存在失败条件,则抛出自己的异常。例如,创建这样一个类

public class RestartServiceException : Exception
{
    public RestartServiceException(string message)
        : base(message)
    {
    }
    // You could also write other constructors with different parameters and use internal logic
    // to process your error message
}
然后,当CheckToRestartService方法中出现失败条件时,使用该类的实例

   if(fail == true)
       throw new RestartServiceException("The service could not be started because .....");
你要么需要

  • applychanges和checkrestartservice中捕获异常
  • 或者您可以通过f.e.传递一个名为
    RestartStatus

    enum RestartStatus{success, unableToRestart, unableToApplySettings};
    
    RestartStatus status = RestartStatus.success;
    applyChangesAndCheckRestartService(status);
    if(status != RestartStatus.success) //....
    
    private void applyChangesAndCheckRestartService(out RestartStatus status)
    {
        // set the status variable accordingly
    }
    
第三种方法是使用您可以单独捕获的方法。

您需要

  • applychanges和checkrestartservice中捕获异常
  • 或者您可以通过f.e.传递一个名为
    RestartStatus

    enum RestartStatus{success, unableToRestart, unableToApplySettings};
    
    RestartStatus status = RestartStatus.success;
    applyChangesAndCheckRestartService(status);
    if(status != RestartStatus.success) //....
    
    private void applyChangesAndCheckRestartService(out RestartStatus status)
    {
        // set the status variable accordingly
    }
    

第三种方法是使用可以单独捕获的函数。

也许您只需要用单独的try/catch块包装不同的函数:

    try {
        if (!ApplyChangesForSettings())
           return;
    }
    catch (Exception ex) {
        MessageBox.Show("Error loading page.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }

    if (svrPortNo != tbSvrPortNo.Text) {      
        try {         
            CommonCodeClass.CheckToRestartService();
        }
        catch (Exception ex) {
            MessageBox.Show("Unable to restart services.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }

或者,如果他们抛出不同的类型,可以考虑捕获不同类型的异常:

string errmsg = string.empty;
try { 
    DoSomething();
}
catch (FooException) {
   errmsg = "There was a Foo error";
}
catch (WidgetException) {
   errmsg = "There was a problem with a Widget";
}
catch (Exception ex) {
   errmsg = "General problem: " + ex.Message;
}

if (!string.IsNullOrEmpty(errmsg))
   MessageBox.Show(errmsg);
另见:


也许您只需要用单独的try/catch块包装不同的函数:

    try {
        if (!ApplyChangesForSettings())
           return;
    }
    catch (Exception ex) {
        MessageBox.Show("Error loading page.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }

    if (svrPortNo != tbSvrPortNo.Text) {      
        try {         
            CommonCodeClass.CheckToRestartService();
        }
        catch (Exception ex) {
            MessageBox.Show("Unable to restart services.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }

或者,如果他们抛出不同的类型,可以考虑捕获不同类型的异常:

string errmsg = string.empty;
try { 
    DoSomething();
}
catch (FooException) {
   errmsg = "There was a Foo error";
}
catch (WidgetException) {
   errmsg = "There was a problem with a Widget";
}
catch (Exception ex) {
   errmsg = "General problem: " + ex.Message;
}

if (!string.IsNullOrEmpty(errmsg))
   MessageBox.Show(errmsg);
另见:


    • 它们是否抛出不同的异常?如果他们这样做,您可以使用异常筛选:

      private void btnApply_Click(object sender, EventArgs e)
      {
          try
          {               
              applyChangesAndCheckRestartService();
          }
      
          // catch service start exceptions
          catch (InvalidOperationException ioex)
          {
              // display message that couldn't start service
          }
      
          // catch rest
          catch (Exception ex)
          {
              MessageBox.Show("Error loading page.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
          }
      }
      
      UPDATE这是假设您正在调用类似于
      ServiceController.Start()
      的函数,该函数在失败时抛出
      InvalidOperationException
      ,您可以在自己的错误条件下轻松抛出该函数,或者创建自己的自定义异常

      if (/* service didn't start */)
      {
          throw new InvalidOperationException("Could not start service.");
      }
      

      它们抛出不同的异常吗?如果他们这样做,您可以使用异常筛选:

      private void btnApply_Click(object sender, EventArgs e)
      {
          try
          {               
              applyChangesAndCheckRestartService();
          }
      
          // catch service start exceptions
          catch (InvalidOperationException ioex)
          {
              // display message that couldn't start service
          }
      
          // catch rest
          catch (Exception ex)
          {
              MessageBox.Show("Error loading page.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
          }
      }
      
      UPDATE这是假设您正在调用类似于
      ServiceController.Start()
      的函数,该函数在失败时抛出
      InvalidOperationException
      ,您可以在自己的错误条件下轻松抛出该函数,或者创建自己的自定义异常

      if (/* service didn't start */)
      {
          throw new InvalidOperationException("Could not start service.");
      }
      

      我喜欢你的主意,但是如何抓住它。我已编辑我的答案以显示重新启动服务功能。请看一看。thanks@user175084对不起,我想我在你的评论中丢失了一些东西。这就是扔ioex的方式吗?是的对不起。。比如如何为它创建一个单独的异常???@user175084对不起,我假设你只是捕获了ServiceController本身在Start()失败时抛出的异常,但是你可以自己轻松地抛出它。我喜欢你的想法,但是如何使用ioex并捕获它。我已编辑我的答案以显示重新启动服务功能。请看一看。thanks@user175084对不起,我想我在你的评论中丢失了一些东西。这就是扔ioex的方式吗?是的对不起。。比如如何为它创建一个单独的异常???@user175084对不起,我假设您只是捕获了ServiceController本身在Start()失败时抛出的异常,但是您可以自己轻松地抛出它。我想这样做。是否有一个示例或示例页面包含上述步骤?其实并不复杂。您需要创建一个从基类异常派生的类。然后可以实现方法或内部变量来表示消息和错误条件。在这里,您可以找到MSDNI的参考资料,他们希望这样做。是否有一个示例或示例页面包含上述步骤?其实并不复杂。您需要创建一个从基类异常派生的类。然后可以实现方法或内部变量来表示消息和错误条件。在这里,您可以从MSDN中找到参考资料