在catch块中捕获异常后,是否可以再次执行try块中的代码

本文关键字:执行 代码 try 是否 捕获异常 catch | 更新日期: 2023-09-27 18:24:18

我想在捕捉到异常后再次执行try块中的代码。这有可能吗?

例如:

try
{
    //execute some code
}
catch(Exception e)
{
}

如果发现异常,我想再次进入try块"执行一些代码",然后再次尝试执行它。

在catch块中捕获异常后,是否可以再次执行try块中的代码

将其放入循环中。可能会在布尔标志周围循环一段时间,以控制您最终想要退出的时间。

bool tryAgain = true;
while(tryAgain){
  try{
    // execute some code;
    // Maybe set tryAgain = false;
  }catch(Exception e){
    // Or maybe set tryAgain = false; here, depending upon the exception, or saved details from within the try.
  }
}

只是要小心避免无限循环。

更好的方法可能是将您的"一些代码"放在自己的方法中,然后您可以根据需要从try和catch中调用该方法。

如果你用一个方法包装你的块,你可以递归地调用它

void MyMethod(type arg1, type arg2, int retryNumber = 0)
{
    try
    {
        ...
    }
    catch(Exception e)
    {
        if (retryNumber < maxRetryNumber)
            MyMethod(arg1, arg2, retryNumber+1)
        else
            throw;
    }
}

或者你可以循环进行。

int retries = 0;
while(true)
{
    try
    {
        ...
        break; // exit the loop if code completes
    }
    catch(Exception e)
    {
        if (retries < maxRetries)
            retries++;
        else
            throw;
    }
}
int tryTimes = 0;
while (tryTimes < 2) // set retry times you want
{
    try
    {
        // do something with your retry code
        break; // if working properly, break here.
    }
    catch
    {
        // do nothing and just retry
    }
    finally
    {
        tryTimes++; // ensure whether exception or not, retry time++ here
    }
}

已在这些(和其他)链接中回答

写重试逻辑而不转到的更好方法

写重试逻辑的最干净的方法?

如何改进此异常重试场景?

还有另一种方法可以做到这一点(尽管正如其他人所提到的,并不是真正推荐的)。下面是一个使用文件下载重试来更紧密地匹配VB6中Ruby中的retry关键字的示例。

RetryLabel:
try
{
    downloadMgr.DownLoadFile("file:///server/file", "c:''file");
    Console.WriteLine("File successfully downloaded");
}
catch (NetworkException ex)
{
    if (ex.OkToRetry)
        goto RetryLabel;
}

我知道社区对goto的看法,但在这种情况下我会(也确实会)使用它。我的一个应用程序运行一个BackgroundWorker,它填充一个ObservableCollection。当BackgroundWorker正在运行并且ObservableCollection正在填充时,我允许通过UI实现一些其他功能,但我需要基于某个时间点的ObservableCollection。所以我做了这个:

long resultCount;           
try_again:
try
{
    //This statement sometimes fails because ocResultList is volatile
    //while the BackgroundWorker is running
    resultCount = <ClassName>.ocResultList.LongCount();
}
catch
{
    goto try_again;
}
if(resultCount...)
{
    //do something
}

做我想做的事-没有意大利面条代码

这应该有效:

count = 0;
while (!done) {
  try{
    //execute some code;
    done = true;
  }
  catch(Exception e){
  // code
  count++;
  if (count > 1) { done = true; }
  }
}

ole goto出了什么问题?

 Start:
            try
            {
                //try this
            }
            catch (Exception)
            {
                Thread.Sleep(1000);
                goto Start;
            }

试试这个:

try {  
  for (var i=0; (i < t && condition) || i === 0; i++) {
    //t is how many times you want the code to run.
    //condition should be true when there is an error.
    //The code you want to execute multiple times if it fails.
  }
} catch (e) {
  
  //The code you want to execute if the code still runs into an error after being repeated multiple times.
  
}

因此,代码将至少运行一次。当代码导致错误时,条件应该为true,因此代码将继续运行,直到i=t,或者条件为false。如果你想在第一个错误后执行一些代码,你可以使用if (i > 0)if (i === 1)来执行