Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.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# 错误原因 ;CS0161:并非所有代码路径都返回值_C#_.net_Dotnet Httpclient - Fatal编程技术网

C# 错误原因 ;CS0161:并非所有代码路径都返回值

C# 错误原因 ;CS0161:并非所有代码路径都返回值,c#,.net,dotnet-httpclient,C#,.net,Dotnet Httpclient,我制作了一个基本的扩展方法,将重试功能添加到我的HttpClient.PostAsync: public static async Task<HttpResponseMessage> PostWithRetryAsync(this HttpClient httpClient, Uri uri, HttpContent content, int maxAttempts, Action<int> logRetry) { if (maxAttempts < 1)

我制作了一个基本的扩展方法,将重试功能添加到我的
HttpClient.PostAsync

public static async Task<HttpResponseMessage> PostWithRetryAsync(this HttpClient httpClient, Uri uri, HttpContent content, int maxAttempts, Action<int> logRetry)
{
    if (maxAttempts < 1)
        throw new ArgumentOutOfRangeException(nameof(maxAttempts), "Max number of attempts cannot be less than 1.");

    var attempt = 1;
    while (attempt <= maxAttempts)
    {
        if (attempt > 1)
            logRetry(attempt);

        try
        {
            var response = await httpClient.PostAsync(uri, content).ConfigureAwait(false);
            response.EnsureSuccessStatusCode();
            return response;
        }
        catch (HttpRequestException)
        {
            ++attempt;
            if (attempt > maxAttempts)
                throw;
        }
    }
}
公共静态异步任务PostWithRetryAsync(此HttpClient HttpClient、Uri、HttpContent内容、int-maxAttempts、操作日志重试)
{
如果(最大尝试次数<1)
抛出新ArgumentOutOfRangeException(nameof(maxAttempts),“最大尝试次数不能小于1”);
var尝试=1;
while(尝试1)
日志重试(尝试);
尝试
{
var response=await-httpClient.PostAsync(uri,内容).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
返回响应;
}
捕获(HttpRequestException)
{
++企图;
如果(尝试>最大尝试)
投掷;
}
}
}
上面的代码给出了以下错误:

错误CS0161“HttpClientExtensions.PostWithRetryAsync(HttpClient,Uri,HttpContent,int,Action)”:并非所有代码路径都返回值


如果我在末尾添加了
抛出新的invalidoOperationException()
(或者
返回null
),错误会像预期的那样消失。我真正想知道的是:是否有任何代码路径在没有返回值或抛出异常的情况下实际退出此方法?我看不见。在这种情况下,我知道的比编译器多,还是相反?

如果它抛出HttpRequestException并执行catch块,它可能会根据条件跳过throw语句(尝试>最大尝试),这样path就不会返回任何内容。

公共静态异步任务PostWithRetryAsync(此HttpClient HttpClient、Uri、HttpContent内容、int-maxAttempts、操作日志重试)
public static async Task<HttpResponseMessage> PostWithRetryAsync(this HttpClient httpClient, Uri uri, HttpContent content, int maxAttempts, Action<int> logRetry)
{
    if (maxAttempts < 1)
        throw new ArgumentOutOfRangeException(nameof(maxAttempts), "Max number of attempts cannot be less than 1.");

    var attempt = 1;
    while (attempt <= maxAttempts)
    {
        if (attempt > 1)
            logRetry(attempt);

        try
        {
            var response = await httpClient.PostAsync(uri, content).ConfigureAwait(false);
            response.EnsureSuccessStatusCode();
            return response;
        }
        catch (HttpRequestException)
        {
            ++attempt;
            if (attempt > maxAttempts)
                throw;
            else
                return something; // HERE YOU NEED TO RETURN SOMETHING
        }
    }
}
{ 如果(最大尝试次数<1) 抛出新ArgumentOutOfRangeException(nameof(maxAttempts),“最大尝试次数不能小于1”); var尝试=1; while(尝试1) 日志重试(尝试); 尝试 { var response=await-httpClient.PostAsync(uri,内容).ConfigureAwait(false); response.EnsureSuccessStatusCode(); 返回响应; } 捕获(HttpRequestException) { ++企图; 如果(尝试>最大尝试) 投掷; 其他的 返回某物;//这里您需要返回某物 } } }
但如果要继续循环,则需要在结束时返回:

    public static async Task<HttpResponseMessage> PostWithRetryAsync(this HttpClient httpClient, Uri uri, HttpContent content, int maxAttempts, Action<int> logRetry)
{
    if (maxAttempts < 1)
        throw new ArgumentOutOfRangeException(nameof(maxAttempts), "Max number of attempts cannot be less than 1.");

    var attempt = 1;
    while (attempt <= maxAttempts)
    {
        if (attempt > 1)
            logRetry(attempt);

        try
        {
            var response = await httpClient.PostAsync(uri, content).ConfigureAwait(false);
            response.EnsureSuccessStatusCode();
            return response;
        }
        catch (HttpRequestException)
        {
            ++attempt;
            if (attempt > maxAttempts)
                throw;               
        }
    }
    return something; // HERE YOU NEED TO RETURN SOMETHING
}
公共静态异步任务PostWithRetryAsync(此HttpClient HttpClient、Uri、HttpContent内容、int-maxAttempts、操作日志重试)
{
如果(最大尝试次数<1)
抛出新ArgumentOutOfRangeException(nameof(maxAttempts),“最大尝试次数不能小于1”);
var尝试=1;
while(尝试1)
日志重试(尝试);
尝试
{
var response=await-httpClient.PostAsync(uri,内容).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
返回响应;
}
捕获(HttpRequestException)
{
++企图;
如果(尝试>最大尝试)
投掷;
}
}
返回某物;//这里您需要返回某物
}

由于错误说明
并非所有代码路径都返回值
您没有为每个代码路径返回值

必须抛出异常或返回值

您可以修改代码,使所有代码路径都返回值

public static async Task<HttpResponseMessage> PostWithRetryAsync(this HttpClient httpClient, Uri uri, HttpContent content, int maxAttempts, Action<int> logRetry)
{
    HttpResponseMessage response = null;
    if (maxAttempts < 1)
        throw new ArgumentOutOfRangeException(nameof(maxAttempts), "Max number of attempts cannot be less than 1.");

    var attempt = 1;
    while (attempt <= maxAttempts)
    {
        if (attempt > 1)
            logRetry(attempt);

        try
        {
            response = await httpClient.PostAsync(uri, content).ConfigureAwait(false);
            response.EnsureSuccessStatusCode();

        }
        catch (HttpRequestException)
        {
            ++attempt;
            if (attempt > maxAttempts)
                throw;
        }
    }
    return response;
}
公共静态异步任务PostWithRetryAsync(此HttpClient HttpClient、Uri、HttpContent内容、int-maxAttempts、操作日志重试)
{
HttpResponseMessage响应=null;
如果(最大尝试次数<1)
抛出新ArgumentOutOfRangeException(nameof(maxAttempts),“最大尝试次数不能小于1”);
var尝试=1;
while(尝试1)
日志重试(尝试);
尝试
{
response=await-httpClient.PostAsync(uri,内容).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
}
捕获(HttpRequestException)
{
++企图;
如果(尝试>最大尝试)
投掷;
}
}
返回响应;
}

原因很简单,编译器必须能够静态验证所有执行流路径是否以返回语句(或异常)结束

让我们看看您的代码,它包含:

  • 一些变量控制
    while
    循环
  • 一个
    while
    循环,嵌入
    return
    语句
  • 循环后无
    return
    语句
因此,编译器基本上必须验证以下内容:

  • 实际执行
    while
    循环
  • 始终执行
    return
    语句
  • 或者总是抛出一些异常
  • 编译器根本无法验证这一点

    让我们尝试一个非常简单的示例:

    public int Test()
    {
        int a = 1;
        while (a > 0)
            return 10;
    }
    
    这个简单的例子将产生完全相同的错误:

    CS0161“Test()”:并非所有代码路径都返回值

    因此,由于以下事实,编译器无法推断:

    • a
      是一个局部变量(意味着只有局部代码才能影响它)
    • a
      的初始值为
      1
      ,并且永不更改
    • 如果
      a
      变量大于零(实际值),则到达
      return
      语句
    然后代码将始终返回值10

    现在看看这个例子:

    public int Test()
    {
        const int a = 1;
        while (a > 0)
            return 10;
    }
    
    唯一的区别是我做了
    a
    a
    const
    。现在它可以编译了,但这是因为优化器现在能够删除整个循环,最终的IL就是这样:

    Test:
    IL_0000:  ldc.i4.s    0A 
    IL_0002:  ret     
    
    return 10;
    
    整个
    while
    循环和局部变量
    return 10;
    
    while (true)
    {
        ...
            if (attempt > maxAttempts)
                throw;
        ...
    }
    
    public int Test()
    {
        while (true)
        {
        }
    }