Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/317.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# 递归异步/等待API调用_C#_Recursion_Async Await - Fatal编程技术网

C# 递归异步/等待API调用

C# 递归异步/等待API调用,c#,recursion,async-await,C#,Recursion,Async Await,我有一个异步方法,可以向供应商发出API调用。供应商要求在发生错误的情况下,我们使用电话中完全相同的信息再打2次电话。对于这个场景,我的第一个想法是使我的API方法递归。然而,在阅读了本网站和其他文章中的许多问题之后,我很难理解async/await如何与递归一起工作 我的方法(为了演示而简化)如下。我不确定我是否应该等待再次出现的电话?Visual Studio抛出该标准,因为此调用未等待,如果我不等待递归调用,执行将继续…等等。当我等待递归调用时,它似乎确实起作用,我只是担心如果我做得不正确

我有一个异步方法,可以向供应商发出API调用。供应商要求在发生错误的情况下,我们使用电话中完全相同的信息再打2次电话。对于这个场景,我的第一个想法是使我的API方法递归。然而,在阅读了本网站和其他文章中的许多问题之后,我很难理解async/await如何与递归一起工作

我的方法(为了演示而简化)如下。我不确定我是否应该等待再次出现的电话?Visual Studio抛出该标准,因为此调用未等待,如果我不等待递归调用,执行将继续…等等。当我等待递归调用时,它似乎确实起作用,我只是担心如果我做得不正确,我会对堆栈做什么。任何帮助都将不胜感激

public async Task<string> GetData(int UserID, int Retry = 0)
{
     try 
     {
         var Request = new HttpRequestMessage(HttpMethod.Post, "myurlhere");
         //Set other request info like headers and payload


         var Response = await WebClient.SendAsync(Request);             
         return await Response.Content.ReadAsStringAsync();         
     } 
     catch (Exception Ex)
     { 
          if (Retry <= 2)
          {
               Retry++;
               return await GetData(UserID, Retry); //Should I await this?
          }
          else 
          {
               return "";
          }
     }
 }
公共异步任务GetData(int UserID,int Retry=0) { 尝试 { var Request=newhttprequestmessage(HttpMethod.Post,“myurlhere”); //设置其他请求信息,如标题和负载 var Response=wait WebClient.SendAsync(请求); return wait Response.Content.ReadAsStringAsync(); } 捕获(例外情况除外) { 如果(重试) 当我等待递归调用时,它似乎确实起作用

太好了

我只是担心如果我做得不对,我会对stack做什么

由于不同步返回的
wait
ing
Task
s由状态机处理,因此在这种情况下,它实际上比“正常”非异步代码对堆栈的负担更小。递归调用成为另一个状态机,对它的引用是第一个状态机中的字段


一般来说,可以采用迭代而不是递归的方法(进行循环并在第一次成功时退出)但实际上,由于即使是非异步等价物也不会有显著的堆栈压力,因此没有必要做任何与您所做的不同的事情。

这不是一种需要递归的情况。正如其他人所建议的,我将使用类似的方法:

public async Task<string> GetDataWithRetry(int UserID, int Tries = 1)
{
    Exception lastexception = null;

    for (int trycount=0; trycount < tries; trycount++)
        try
        {
            return await GetData(UserID);
        }
        catch (Exception Ex)
        {
            lastexception = Ex;
        }

    throw lastexception;
}

public async Task<string> GetData(int UserID)
{
     var Request = new HttpRequestMessage(HttpMethod.Post, "myurlhere");
     //Set other request info like headers and payload


     var Response = await WebClient.SendAsync(Request);             
     return await Response.Content.ReadAsStringAsync();         
}
public异步任务GetDataWithRetry(int UserID,int trys=1)
{
异常lastexception=null;
for(int-trycount=0;trycount我会考虑把这个问题推到一个堆栈上。留下原来的代码> GETDATABOS/CODE >,并建立一个<代码> GETDATA.ReTrime>代码>函数,捕获异常并重试到X次。这是不需要递归的,并且你有明确的名字来表示他们做了什么。Works。在我看来,结果会回到catch块。@狗仔队为什么会有问题?这不是一个递归问题,而是一个重复问题。递归应该用在可以通过将问题分解成更小版本来解决问题的地方。这里不是这种情况。我会按照@mjwills的思路做一些事情建议。谢谢你写出来!我想我误解了你和mjwills的建议。你正在清除抛出异常的堆栈跟踪,这使调试变得更加困难。@Servy这不是可用于生产的代码。它有一些错误。它只是演示了重试的想法。这就是我说“类似”的原因.@Mike,你试图证明的是你做错了什么。如果你发布的代码有很多错误,那么人们最终会做错误的事情,因为你告诉他们这就是解决方案。如果这是一个与核心问题的实际解决方案不相关的代码问题,那么它将是错误的一个问题的答案是肯定的,但事实并非如此。@Servy我想我已经把重试的想法传达给了OP,但你有一点认为它不是一个完整的解决方案。你如何回答这个问题?