現在,讓我們來使用委派方法的功能,在這個練習中,我們將會設計一個類別,他會下載一個網路 PDF 檔案,當在下載的過程之中,會將下載檔案的實際讀取到的檔案完成百分比,透過委派方法回報;這個委派方法扮演著一個類似事件,也就是可以接收到處理工作當時狀態的通知,所以,訂閱這個委派事件的用戶端,就可以即時下載進度顯示在螢幕上,讓使用者明瞭這個長時間的工作,現在處理到甚麼進度了。
在這個類別 DownloadFile,我們定義了一個 Download 函式,他使用了 HttpClient.GetAsync 方法,抓取指定 URL 的內容,並且使用 HTTP Header 的
Content-Length
得到要下載的檔案總大小,接著,取得 HttpResponseMessage 之後,使用 HttpResponseMessage.Content.ReadAsStreamAsync() 方法,取得 Stream 行別的物件,便可以開始每次讀取 5120 bytes 大小的內容到程式中。每次完成讀取 5120 bytes,就會呼叫委派方法 onProgress,將處理進度回報,而這個 onProgress 是個委派型別的變數 public delegate void ProgressDelegate(int percent);
。 public class DownloadFile
{
public delegate void ProgressDelegate(int percent);
public ProgressDelegate OnProgress;
public string Url { get; set; } = "http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/js_api_reference.pdf";
public async void Download()
{
var task = Task.Factory.StartNew(async () =>
{
int offset = 5120;
int percent = 0;
int currentDonload = 0;
int getBytes;
int lastPercent = -1;
using (var client = new HttpClient())
{
using (var response = await client.GetAsync(Url))
{
var total = int.Parse(response.Content.Headers.First(h => h.Key.Equals("Content-Length")).Value.First());
byte[] content = new byte[total];
using (var stream = await response.Content.ReadAsStreamAsync())
{
var onProgress = OnProgress;
while ((getBytes = stream.Read(content, currentDonload, offset)) > 0)
{
currentDonload += getBytes;
percent = (int)((1.0*currentDonload / total) * 100);
if (lastPercent != percent)
{
if (onProgress != null)
{
onProgress(percent);
}
lastPercent = percent;
}
}
}
}
}
});
}
}
在進行測試的時候,我們建立了這個類別 (DownloadFile) 物件,接者設定 OnProgress 委派欄位,使其綁定到 DownloadStatus 方法上;這個方法就會將現在的處理進度,即時顯示在螢幕上,讓使用者知道現在的處理最新情況。
static void Main(string[] args)
{
DownloadFile downloadFile = new DownloadFile();
downloadFile.OnProgress += DownloadStatus;
Console.WriteLine($"開始進行非同步檔案檔案下載");
downloadFile.Download();
Console.WriteLine($"Press any key to Exist...{Environment.NewLine}");
Console.ReadKey();
}
private static void DownloadStatus(int percent)
{
if(percent%10==0)
{
Console.Write($" {percent}% ");
}
else
{
Console.Write($".");
}
}
底下是執行結果
開始進行非同步檔案檔案下載
Press any key to Exist...
0% ......... 10% ......... 20% ......... 30% ......... 40% ......... 50% ......... 60% ......... 70%