ASP .NET Rest API重复调用另一个API

时间:2018-10-05 13:12:24

标签: c# asp.net-web-api

如何才能按时间间隔重复调用URL,直到获得成功的结果或超时?

我将文件上传到API,它向我发送一个URL,让我检查文件是否已成功处理。我要这样做,以便在服务器中检查此URL,直到更改挂起状态。有successfulfailedpending状态。我想让用户等到结果失败或成功。

[HttpGet]
public async Task<ActionResult> Get()
{
    ...
    response = await client.GetAsync(other_api_url);

    if(response.IsSuccessStatusCode)
    {
        string result = response.Content.ReadAsStringAsync().Result;
        dynamic output = JsonConvert.DeserializeObject<dynamic>(result);

        statusUrl = output.url_to_check_status;

        //make a call to statusUrl check if content is ready
        //get result and parse it
        ...

        status = output.status;

        if(status == "SUCCESS")
        {
            //good path
            return Ok();
        }
        else
        {
            //make another call after n seconds to check again
        }
    }

    return NotFound();
}

2 个答案:

答案 0 :(得分:2)

并非我同意这样做(您永远不要以这种方式阻止您的请求),但是我认为这应该可以解决您的问题:

[HttpGet]
public async Task<ActionResult> Get()
{
    response = await client.GetAsync(other_api_url);

    if(response.IsSuccessStatusCode)
    {
        // DO NOT USE `.Result` within async method.
        string result = await response.Content.ReadAsStringAsync();
        dynamic output = JsonConvert.DeserializeObject<dynamic>(result);

        statusUrl = output.url_to_check_status;

        bool? result = null;
        while(result == null) result = await CheckIfSuccessfulAsync(statusUrl);

        if (result) return Ok();       
        return NotFound();
    }
}

// Does not *need* to be a separate method, it's just for better readability...
private async Task<bool?> CheckIfSuccessfulAsync(string statusUrl)
{    
    //make a call to statusUrl check if content is ready
    //get result and parse it
    ...

    status = output.status;

    if (status == "SUCCESS") return true;
    else if (status == "PENDING") return false;

    return null;
}

答案 1 :(得分:2)

您可以对Task.Delay使用循环,如下所示:

bool done = false;
while (!done)
{
    await Task.Delay(1000);
    done = await GetStatusFromServerAsync();
}

尽管您可能需要超时:

async Task<bool> CheckForCompletion(int timeoutms)
{
    var timer = StopWatch.StartNew();
    while (timer.ElapsedMilliseconds < timeoutms)
    {
        var ok = await GetStatusFromServerAsync();
        if (ok) return true;
        await Task.Yield(1000);
    }
    return false;
}