如何重构代码以删除 C# 应用程序中的 break 语句

How can I refactor the code in order to remove the break statement in a C# application

我有一个 C# Windows 应用程序,我在其中使用以下代码调用 API:

while (true)
{
    try
    {
        using (HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, "Some URL"))
        {
            requestMessage.Headers.Add("Accept", "application/json");                                
            response = await myHttpHelper.SendHttpRequest(requestMessage).ConfigureAwait(false);                             
        }
        break; // where the code smells is shown
    }
    catch (TaskCanceledException )
    {
        if (++attemptCount > 3)
        {
            throw;
        }
        Thread.Sleep(10000);
    }
    catch (Exception ex2)
    {
        throw;
    }
}

通常发生的情况是,当出现网络问题时,对 API 的获取请求会被取消。所以我所做的是每当任务被取消时,我都会尝试三次。如果它不起作用,那么我会向调用方法抛出异常。如果在这 3 次尝试中都成功,我将打破循环。

现在,当我 运行 对我的代码进行 Sonar 分析时,它显示要删除 break 语句并重构代码。我该怎么做?

while (true) 是一个无限循环。 相反,我宁愿使用(布尔)变量来检查 while()。 这使您有机会将此变量设置为 false 并避免 break.

你通常不应该使用 while (true)(那是一个潜在的无限循环),即使你在某处有一个 break 语句,但有时可能会发生无法达到该语句的情况。

我会推荐一个 for 循环:

for (int i = 0; i < 3; i++)
{
    try
    {
        using (HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, "Some URL"))
        {
            requestMessage.Headers.Add("Accept", "application/json");                                
            response = await myHttpHelper.SendHttpRequest(requestMessage).ConfigureAwait(false);                             
        }
    }
    catch (TaskCanceledException)
    {
        Thread.Sleep(10000);
    }
    catch (Exception ex2)
    {
        throw;
    }
}

创建一个名为 success 的布尔变量并将其用作 while 循环条件:

boolean success = false;
while (!success) {
    try
    {
        using (HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, "Some URL"))
        {
            requestMessage.Headers.Add("Accept", "application/json");                                
            response = await myHttpHelper.SendHttpRequest(requestMessage).ConfigureAwait(false);                             
        }
        success = true; <--- set to true here
    }
    ...
}

如果您不选择 Polly,我会推荐@Sweeper 和@Magnus 的回复组合:

const int retryLimit = 3;
boolean success = false;
int retryCounter = 0;

while (!success
        && retryCounter++ < retryLimit) {
    try
    {
        // http request as is

        success = true; 
    }
    // Exception handling
}

这样可以控制重试次数并且请求成功后跳出循环