我有一个异步方法,可以对供应商进行API调用。供应商要求在发生错误的情况下,我们再打两次电话,并在电话中提供完全相同的信息。对于这种情况,我的第一个想法是使我的API方法递归。但是,在查看了本网站上的许多问题和其他文章之后,我很难理解异步/等待如何与递归一起工作。
我的方法(为演示而简化)如下。我不确定是否应该等待电话咨询? 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 "";
}
}
}
答案 0 :(得分:1)
当我等待递归调用时,它确实可以工作,
太好了。
如果我做错了,我只是担心自己要做什么。
由于await
导致Task
不同步返回是由状态机处理的,因此与“正常”非正常情况相比,在这种情况下实际上减轻了堆栈负担-异步代码。递归调用成为另一个状态机,对其的引用是第一个状态机中的一个字段。
通常可以采用迭代而不是递归的方法(有一个循环并在首次成功时退出),但是实际上,即使非异步等效物也不会产生很大的堆栈压力,因此无需做任何不同的事情比你做的要好。
答案 1 :(得分:0)
这不是需要递归的情况。正如其他人所建议的那样,我会使用类似这样的东西:
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();
}