2017年10月30日 星期一

C# HttpClient WebAPI : 18. 套用 ProgressMessageHandler ,訂閱請求與回應的資料傳輸事件

在前面的練習中,我們有做到當要知道 HttpClient 下載一個大檔案的時候,我們可以做到這個檔案的下載處理進度;可是,當我們需要做到檔案上傳或者是多個檔案一次性的上傳或者下載、又或者當資料封裝的內容過多、雖然傳輸與接收內容不多,但是網路速度可能會過慢的情況下,我們還是期望能夠知道 HttpClient 進行 請求 Request 與 回應 Response 的當時處理進度,我們需要有這樣的事件可以訂閱,以便我們可以針對觸發這些事件之後,進行相關的反應動作。
最快速又方便的解決方案,就是使用剛剛提到的 
C# HttpClient WebAPI : 17. 有趣的 HttpClient 管道,自訂 HttpMessage Handler
 Http 訊息處理器來實現這個需求


了解更多關於 [HttpClient Class] 的使用方式
了解更多關於 [使用 async 和 await 進行非同步程式設計] 的使用方式


套用 ProgressMessageHandler ,訂閱請求與回應的資料傳輸事件

在這裡,我們需要使用 ProgressMessageHandler 類別來幫我們做到這樣工作,這裡類別有這兩個事件:HttpReceiveProgress / HttpSendProgress,分別表示當 HttpClient 進行請求與回應網路存取行為的時候,就會適時觸發這兩個事件,此時,用戶端就可以根據這樣的觸發事件行為,做出適當的處理。
在我們這個練習中,我們將訂閱者的回應事件方法,透過委派的方式,傳送到我們要使用 HttpClient 方法內,並且,加入到訂閱事件內。
在這裡,您也可以學會如何將委派方法,傳送到別的方法內,並且加入成為事件訂閱者,這樣的程式設計技巧。
為了要使用 ProgressMessageHandler 類別,我們需要在專案內加入 System.Net.Http.Formatting.Extension 這個 NuGet 套件
我們先宣告了一個 HttpProgressDelegate 委派類別,與兩個訂閱事件函示,這兩個函示將會分別表示當 HttpClient 進行網路存取行為的時候,將會用到的 CallBack 方法,為了簡化展示,我們僅僅列印出訊息文字到螢幕上。
在這裡,我們先宣告了一個 HttpProgressDelegate 委派類別
delegate void HttpProgressDelegate(object request, HttpProgressEventArgs e);
我們也設計兩個方法,這兩個方法將會以傳入到上傳圖片與下載圖片的方法內,並且會加入到 ProgressMessageHandler.HttpReceiveProgress 與 ProgressMessageHandler.HttpSendProgress 事件內,這樣,一旦有任何符合條件的事件發生了,就會觸發這些訂閱事件方法。
private static void Program_HttpSendProgress(object sender, HttpProgressEventArgs e)
{
    Console.WriteLine($"Send : {e.ProgressPercentage}");
}

private static void Program_HttpReceiveProgress(object sender, HttpProgressEventArgs e)
{
    Console.WriteLine($"Receive : {e.ProgressPercentage}");
}
最後,我們會在上傳與下載的方法內,建立 ProgressMessageHandler 類別物件,接著,設定 Http 訊息處理器的管道連結,綁定相關事件。
ProgressMessageHandler progressMessageHandler = new ProgressMessageHandler();
progressMessageHandler.InnerHandler = handler;
progressMessageHandler.HttpReceiveProgress += new EventHandler<HttpProgressEventArgs>(onHttpResponseProgress);
progressMessageHandler.HttpSendProgress += new EventHandler<HttpProgressEventArgs>(onHttpRequestProgress);

using (HttpClient client = new HttpClient(progressMessageHandler))

進行測試

在程式進入點函式,我們直接呼叫 HttpGetAsync 這個非同步方法。
static async Task Main(string[] args)
{

    //HttpReceiveProgress += Program_HttpReceiveProgress;
    //HttpSendProgress += Program_HttpSendProgress; ;

    Console.WriteLine($"上傳圖片且有進度回報");
    await UploadImageAsync("vulcan.png", Program_HttpSendProgress, Program_HttpReceiveProgress);
    Console.WriteLine($"Press any key to Exist...{Environment.NewLine}");
    Console.ReadKey();

    Console.WriteLine($"下載圖片且有進度回報");
    await DownloadImageAsync("vulcan.png", Program_HttpSendProgress, Program_HttpReceiveProgress);
    Console.WriteLine($"Press any key to Exist...{Environment.NewLine}");
    Console.ReadKey();
}

執行結果

這個測試將會輸出底下內容
上傳圖片且有進度回報
Send : 0
Send : 0
Send : 2
Send : 5
Send : 7
Send : 10
Send : 12
Send : 15
Send : 17
Send : 20
Send : 23
Send : 25
Send : 28
Send : 30
Send : 33
Send : 35
Send : 38
Send : 40
Send : 43
Send : 46
Send : 48
Send : 51
Send : 53
Send : 56
Send : 58
Send : 61
Send : 63
Send : 66
Send : 68
Send : 71
Send : 74
Send : 76
Send : 79
Send : 81
Send : 84
Send : 86
Send : 89
Send : 91
Send : 94
Send : 97
Send : 99
Send : 99
Send : 100
Receive : 0
Press any key to Exist...

 下載圖片且有進度回報
Receive : 2
Receive : 3
Receive : 5
Receive : 7
Receive : 9
Receive : 11
Receive : 14
Receive : 17
Receive : 19
Receive : 20
Receive : 22
Receive : 23
Receive : 26
Receive : 28
Receive : 31
Receive : 33
Receive : 36
Receive : 39
Receive : 41
Receive : 43
Receive : 46
Receive : 47
Receive : 49
Receive : 52
Receive : 54
Receive : 57
Receive : 59
Receive : 62
Receive : 64
Receive : 67
Receive : 70
Receive : 72
Receive : 75
Receive : 77
Receive : 80
Receive : 82
Receive : 84
Receive : 86
Receive : 88
Receive : 90
Receive : 93
Receive : 95
Receive : 98
Receive : 100
Press any key to Exist...

相關文章索引

C# HttpClient WebAPI 系列文章索引


了解更多關於 [HttpClient Class] 的使用方式
了解更多關於 [使用 async 和 await 進行非同步程式設計] 的使用方式


關於 Xamarin 在台灣的學習技術資源

Xamarin 實驗室 粉絲團
歡迎加入 Xamarin 實驗室 粉絲團,在這裡,將會經常性的貼出各種關於 Xamarin / Visual Studio / .NET 的相關消息、文章、技術開發等文件,讓您可以隨時掌握第一手的 Xamarin 方面消息。
Xamarin.Forms @ Taiwan
歡迎加入 Xamarin.Forms @ Taiwan,這是台灣的 Xamarin User Group,若您有任何關於 Xamarin / Visual Studio / .NET 上的問題,都可以在這裡來與各方高手來進行討論、交流。
Xamarin 實驗室 部落格
Xamarin 實驗室 部落格 是作者本身的部落格,這個部落格將會專注於 Xamarin 之跨平台 (Android / iOS / UWP) 方面的各類開技術探討、研究與分享的文章,最重要的是,它是全繁體中文。
Xamarin.Forms 系列課程
Xamarin.Forms 系列課程 想要快速進入到 Xamarin.Forms 的開發領域,學會各種 Xamarin.Forms 跨平台開發技術,例如:MVVM、Prism、Data Binding、各種 頁面 Page / 版面配置 Layout / 控制項 Control 的用法等等,千萬不要錯過這些 Xamarin.Forms 課程


沒有留言:

張貼留言