问题描述
我已经实现了这段代码,现在两周了。从那时起,我试图改进我的代码,因为有时 Task.Delay 方法不足以等待 3rd 方 API 发送我需要的正确 http 状态代码。 (他们的处理时间比我预期的要长得多。)
var url = string.Format(_azureFormRecognizerConfig.RequestUrl,_azureFormRecognizerConfig.ResourceUrl,modelId);
var content = new StringContent(JsonConvert.SerializeObject(new { source = storagePath }),Encoding.UTF8,_azureFormRecognizerConfig.MediaType);
using (var httpClient = new HttpClient())
{
// Request headers
httpClient.DefaultRequestHeaders.Add(_azureFormRecognizerConfig.SubscriptionType,_azureFormRecognizerConfig.SubcriptionKey);
using (var response = await httpClient.PostAsync(url,content))
{
try
{
response.EnsureSuccessstatusCode();
responseLocationUri = response.Headers.GetValues("Operation-Location").FirstOrDefault();
}
catch (HttpRequestException ex)
{
_logger.information($"Error in httpclient { ex.Message } ");
}
}
Task.Delay(20000).Wait();
using (var response = await httpClient.GetAsync(responseLocationUri))
{
try
{
response.EnsureSuccessstatusCode();
responseBody = await response.Content.ReadAsstringAsync();
}
catch (HttpRequestException ex)
{
_logger.information($"Error in httpclient { ex.Message } ");
}
}
_logger.information($"Response headers { responseBody }");
}
正如您在我的代码中看到的,我设置了 20,000 毫秒(20 秒)的延迟来处理逻辑,并期望在这段时间内完成该过程并且我可以获得正确的响应和值。
无论如何,我该如何改进或使其像回调或我仍然没有发现的东西一样工作。
谢谢!
解决方法
我假设 API 是这样工作的:
- 您发布一个帖子,这会在服务器上启动一些计算。
- 您使用从 Post 返回的 url 进行 Get。如果计算完成,这将成功,否则将失败。
要管理这个,你应该使用轮询,即
while(true){
using (var response = await httpClient.GetAsync(responseLocationUri)){
if(response.IsSuccessStatusCode){
// Handle success case
return someResult;
}
await Task.Delay(1000); // Wait 1s between each attempt
}
}
如果服务器从不响应,您可能还应该添加超时或检查返回的错误代码类型以避免永远轮询。
如果您可以更改 API,那么使用某种 callback 而不是使用轮询也可能是有意义的,因为回调通常会导致使用更少的资源。