Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 什么时候处理异常?_C#_Exception Handling - Fatal编程技术网

C# 什么时候处理异常?

C# 什么时候处理异常?,c#,exception-handling,C#,Exception Handling,我正在编写一个应用程序,可以通过多个步骤为任务提供信息。我有一些类似于下面的代码,我想知道这是否是处理异常的正常方法。这段代码可能永远不会被其他人看到,但它可能是,所以我想知道我正在像任何人所期望的那样处理异常 IEnumerable<Task> Tasks; foreach(var task in Tasks) { try { //boiler plate prep for task (loading libraries, connecting, logging sta

我正在编写一个应用程序,可以通过多个步骤为任务提供信息。我有一些类似于下面的代码,我想知道这是否是处理异常的正常方法。这段代码可能永远不会被其他人看到,但它可能是,所以我想知道我正在像任何人所期望的那样处理异常

IEnumerable<Task> Tasks;

foreach(var task in Tasks)
{
 try
 {
   //boiler plate prep for task (loading libraries, connecting, logging start, etc)

   foreach(var step in task.Steps)
   {  
      try
      {
        step.Execute();
      }
      catch(Exception ex)
      {
        LogStepError(step, ex);
        throw;
      }
    }

    //Notify parties task has been completed successfully, log task completion
  }
  catch(Exception ex)
  {
      LogTaskFailure(task);
  }
  finally
  {
    //close connections, etc
  }
}



interface ITaskStep
{
    void Execute()
    {

    }            
}
i可数任务;
foreach(任务中的var任务)
{
尝试
{
//锅炉板准备任务(加载库、连接、记录启动等)
foreach(task.Steps中的var步骤)
{  
尝试
{
step.Execute();
}
捕获(例外情况除外)
{
LogStepError(步骤,ex);
投掷;
}
}
//通知各方任务已成功完成,记录任务完成
}
捕获(例外情况除外)
{
LogTaskFailure(任务);
}
最后
{
//密切联系等
}
}
接口ITaskStep
{
void Execute()
{
}            
}

我还想补充一点,任务步骤正在实现ITaskStep接口,因此Execute的实现不是我自己的(在本例中是这样的,但是有人可以实现接口)。我的代码只是加载库并运行任何iTask及其ITaskSteps。

当我有一个任务列表,即使其中一些任务失败,我也要完成类似次数的任务。事实上,有时我知道有一个很好的机会失败,但我不想打破循环,直到所有步骤都完成

我认为这很有意义。

如果for循环中只发生了
step.Execute()

i可数任务;
foreach(任务中的var任务)
{
尝试
{
//锅炉板准备工作
}
捕获(例外情况除外)
{
LogTaskFailure(任务);
继续;
}
foreach(task.Steps中的var步骤)
{  
尝试
{
step.Execute();
}
捕获(例外情况除外)
{
LogStepError(步骤,ex);
LogTaskFailure(任务);
打破
}
}
}
类任务步骤
{
私有void Execute()
{
//做一些事情,不要捕捉任何异常
}            
}

这样您就不会重新显示异常。

我想我可能是这样写的,但是您的方法也可以工作

foreach(var step in task.Steps)
       {  
          try
          {
            step.Execute();
          }
          catch(Exception ex)
          {
            LogStepError(step, ex);
            LogTaskFailure(task);
            break;
          }
        }

您可能希望使用返回变量来处理任务的完成,并在整个代码中使用Exception来捕获任何通用异常

例如:

try{
foreach(var step in task.Steps)
       {  
            if(!step.Execute()){
                break;
            }

        }
}catch(Exception ex)
{
}

您正在捕获所有异常,这是可以的,正如您提到的,这是最常见的方法,但我认为这不是正确的方法

我认为你应该抓住具体的例外情况。如果你这样做了,你可以把它们分开,你会注意到有些例外情况你根本无法处理,但有些例外情况你可以处理。代码将变得更好、更健壮,因为您将确切地知道代码上发生了什么

这是一个例子:



try
{
     //Your stuff
}
catch(DivideByZeroException ex)
{
   //Could you manage this?
}
catch(NullReferenceException ex)
{
   //Could you manage this one?
}
catch(IOException ex)
{
      //What about this one?
}
finally
{
      //Any cleanup code
}


继续捕获异常以记录它们的存在。但是,如果您还没有真正解决导致抛出异常的问题,那么请重新抛出该异常以供调用方处理。不要吞下它

上面的代码捕获一个
taskisboguseException
和一个
PrinterOnFireException
并以相同的方式处理它们:记录它并继续执行下一个任务。用一个虚假的任务来做这件事是可以的,因为你已经完成了任务,但是如果你发现了一个
printeronfirefexception
,并且没有重新启动它,那么天哪,打印机最好不要仍然着火


如果您不打算重新调用,那么只捕获代码知道如何处理的特定异常类型。让其他所有内容(无论是您不知道如何处理的内容,还是您从未想过的内容)传播到下一个可用的异常处理程序。

锅炉板准备是在循环之外发生的一些其他内容,我想在try/catch中进行包装。它提取一些库依赖项并将它们写入磁盘以备将来使用,以及连接到远程系统等。使用此代码,如果boiler plate代码引发异常,则不会执行更多任务,这不是我想要的。我还需要使用finally块来处理任何连接。我想我的第一个例子不是最具代表性的。我计划在将来做类似的事情,但我需要先弄清楚一般的设置。


try
{
     //Your stuff
}
catch(DivideByZeroException ex)
{
   //Could you manage this?
}
catch(NullReferenceException ex)
{
   //Could you manage this one?
}
catch(IOException ex)
{
      //What about this one?
}
finally
{
      //Any cleanup code
}