延遲呼叫或多次呼叫第三方的Web API服務
阿新 • • 發佈:2019-02-02
當我們呼叫第三方的Web API服務的時候,不一定每次都是成功的。這時候,我們可能會再多嘗試幾次,也有可能延遲一段時間再去嘗試呼叫服務。
Task的靜態方法Delay允許我們延遲執行某個Task,此方法可以讓我們做到延遲一段時間再去呼叫服務;多嘗試幾次呼叫如何實現呢?可以用迴圈遍歷。
在ASP.NET Web API專案的同一個解決方案下建立一個控制檯應用程式。
依次點選"工具","庫程式包管理器","程式包管理器控制檯",輸入如下:
Install-Package Microsoft.AspNet.WebApi.Client
注意:是為新的控制檯專案新增包,在"預設專案"選項下要選擇剛建立的控制檯專案,並且把它設定為啟動專案。
首先使用Task的Delay方法,來做一個簡單的試驗。
static void Main(string[] args)
{
Task<int> t = Task.Factory.StartNew(() => GetSth(2));
Console.WriteLine(DelayResult(t.Result, TimeSpan.FromSeconds(5)).Result);
Console.ReadKey();
}
static async Task<T> DelayResult<T>(T result, TimeSpan delay)
{
await Task.Delay(delay);
return result;
}
static int GetSth(int a)
{
return a;
}
結果發現,的確是延遲呼叫了Task,顯示結果的時候有延遲。
然後使用HttpClient來呼叫Web API服務,寫2個方法,一個方法嘗試4次,一秒鐘後重試,然後2秒鐘後重試,再然後4秒鐘後重試,最後再嘗試一次;另外一個方法嘗試2次,嘗試一次後,再隔一段時間嘗試。
static void Main(string[] args)
{
Console.WriteLine(DownloadStringWithRetries("/api/Product/1").Result);
Console.WriteLine(DownloadStringWithTimeout("/api/Product/1").Result);
Console.ReadKey();
}
//嘗試4次,一秒鐘後重試,然後2秒鐘後重試,再然後4秒鐘後重試,最後嘗試一次
static async Task<string> DownloadStringWithRetries(string uri)
{
using (var client = new HttpClient())
{
//設定
client.BaseAddress = new Uri("http://localhost:1310/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//一秒鐘後重試,然後2秒鐘後重試,再然後4秒鐘後重試
var nextDelay = TimeSpan.FromSeconds(1);
for (int i = 0; i != 3; ++i)
{
try
{
return await client.GetStringAsync(uri);
}
catch
{
}
await Task.Delay(nextDelay);
nextDelay = nextDelay + nextDelay;
}
//最後再試一次
return await client.GetStringAsync(uri);
}
}
//嘗試2次,嘗試一次後,再隔一段時間嘗試
static async Task<string> DownloadStringWithTimeout(string uri)
{
using (var client = new HttpClient())
{
//設定
client.BaseAddress = new Uri("http://localhost:1310/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var downloadTask = client.GetStringAsync(uri);
var timeoutTask = Task.Delay(3000);
//如果Web API服務沒有在3秒響應,就返回null
var completedTask = await Task.WhenAny(downloadTask, timeoutTask);
if (completedTask == timeoutTask)
{
return null;
}
return await downloadTask;
}
}