延遲調用或多次調用第三方的Web API服務

當我們調用第三方的Web API服務的時候,不一定每次都是成功的。這時候,我們可能會再多嘗試幾次,也有可能延遲一段時間再去嘗試調用服務。

 

Task的靜態方法Delay允許我們延遲執行某個Task,此方法可以讓我們做到延遲一段時間再去調用服務;多嘗試幾次調用如何實現呢?可以用循環遍歷。

 

在"使用HttpClient對ASP.NET Web API服務實現增刪改查"中,創建了一個ASP.NET Web API項目,本篇沿用此Web API服務。

 

在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;
            }
        }

 

1

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章