zoukankan      html  css  js  c++  java
  • 一个简单的利用 WebClient 异步下载的示例(一)

    继上一篇文章 一个简单的利用 HttpClient 异步下载的示例 ,我们知道不管是 HttpClient,还算 WebClient,都不建议每次调用都 new HttpClient,或 new WebClient,而应该尽量重复对象,可以把一个 WebClient(或 HttpClient)理解成一个浏览器,不能没打开一个页面以后,就销毁它,再重新创建一个,这样会有性能损失,而建议一个线程共用一个 WebClient(或 HttpClient)。这一次,我们利用 WebClient 来实现异步下载,这一次,我们增加一个进度条来显示进度。

    直接提代码了:

    1. TaskDemo101

    优化后的 TaskDemo101 类:

         public static class TaskDemo101
        {
            public static string GetRandomUrl()
            {
                string url1 = "http://www.xxx.me/Uploads/image/20130129/2013012920080761761.jpg";
                string url2 = "http://www.xxx.me/Uploads/image/20121222/20121222230686278627.jpg";
                string url3 = "http://www.xxx.me/Uploads/image/20120606/20120606222018461846.jpg";
                string url4 = "http://www.xxx.me/Uploads/image/20121205/20121205224383848384.jpg";
                string url5 = "http://www.xxx.me/Uploads/image/20121205/20121205224251845184.jpg";
    
                string resultUrl;
                int randomNum = new Random().Next(1, 6);
                switch (randomNum)
                {
                    case 1: resultUrl = url1; break;
                    case 2: resultUrl = url2; break;
                    case 3: resultUrl = url3; break;
                    case 4: resultUrl = url4; break;
                    case 5: resultUrl = url5; break;
                    default: throw new Exception("");
                }
                return resultUrl;
            }
    
            public static string GetSavedFileFullName()
            {
                string targetFolderDestination = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "downloads\images\");
                try
                {
                    Directory.CreateDirectory(targetFolderDestination);
                }
                catch (Exception)
                {
                    Console.WriteLine("创建文件夹失败!");
                }
                string targetFileDestination = Path.Combine(targetFolderDestination, string.Format("img_{0}.png", DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss")));
                return targetFileDestination;
            }
    
            public static async Task<bool> RunByHttpClient(SkyHttpClient skyHttpClient, int id)
            {
                var task = skyHttpClient.DownloadImage(GetRandomUrl());
                return await task.ContinueWith<bool>(t => {
                    File.WriteAllBytes(GetSavedFileFullName(), t.Result);
                    return true;
                });
            }
    
            public static void RunByWebClient(WebClient webClient, int id)
            {
                webClient.DownloadFileAsync(new Uri(GetRandomUrl()), GetSavedFileFullName());
            }
        }

    2. Form1 

    这一次我们的 Form1 实现了 INotifyPropertyChanged 接口

        public partial class Form1 : Form, INotifyPropertyChanged
        {
            #region 字段、属性
    
            public event PropertyChangedEventHandler PropertyChanged;
            private void OnPropertyChanged(string prop)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(prop));
                }
            }
            WebClient webc = new WebClient();
            bool _canChange = true;
            public bool CanChange
            {
                get
                {
                    return _canChange;
                }
                set
                {
                    _canChange = value;
                    OnPropertyChanged("CanChange");
                }
            }
    
            #endregion
    
            public Form1()
            {
                InitializeComponent();
                webc.DownloadFileCompleted += Webc_DownloadFileCompleted; //注册下载完成事件
                webc.DownloadProgressChanged += Webc_DownloadProgressChanged; //注册下载进度改变事件
            }
    
            private List<int> GetDownloadIds()
            {
                List<int> ids = new List<int>(100);
                for (int i = 1; i <= 100; i++)
                {
                    ids.Add(i);
                }
                return ids;
            }
    
            private void WhenAllDownloading()
            {
                this.listBoxLog.Items.Insert(0, string.Format("当前时间:{0},准备开始下载...", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
                //禁用按钮
                EnableOrDisableButtons(false);
            }
    
            private void EnableOrDisableButtons(bool enabled)
            {
                this.btnRunByHttpClient.Enabled = enabled;
                this.btnRunByWebClient.Enabled = enabled;
            }
    
            private void WhenSingleDownloaded(int id, bool singleDownloadSuccess)
            {
                this.listBoxLog.Items.Insert(0, string.Format("当前时间:{0},编号 {1} 下载 {2}!", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), id, singleDownloadSuccess));
            }
    
            private void WhenAllDownloaded()
            {
                this.listBoxLog.Items.Insert(0, string.Format("当前时间:{0},下载完毕!", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
                //启用按钮
                EnableOrDisableButtons(true);
            }
    
            private async void btnRunByHttpClient_Click(object sender, EventArgs e)
            {
                SkyHttpClient skyHttpClient = new SkyHttpClient();
                try
                {
                    WhenAllDownloading();
                    foreach (var id in GetDownloadIds())
                    {
                        bool singleDownloadSuccess = await TaskDemo101.RunByHttpClient(skyHttpClient, id);
                        WhenSingleDownloaded(id, singleDownloadSuccess);
                    }
                    WhenAllDownloaded();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Download Error!");
                }
            }
    
            private void btnRunByWebClient_Click(object sender, EventArgs e)
            {
                if (CanChange)
                {
                    WhenAllDownloading();
                    CanChange = false;
    
                    ToDownload.Clear();
                    foreach (var id in GetDownloadIds())
                    {
                        ToDownload.Enqueue(id);
                    }
    
                    progressBar1.Maximum = ToDownload.Count * 100;
                    btnRunByWebClient.Text = "用 WebClient 暂停下载";
    
                    int firstId = ToDownload.Dequeue();
                    TaskDemo101.RunByWebClient(webc, firstId);
                    WhenSingleDownloaded(firstId, true);
                }
                else
                {
                    ToDownload.Clear();
                    webc.CancelAsync();
                    CanChange = true;
                    progressBar1.Value = 0;
                    btnRunByWebClient.Text = "用 WebClient 开始下载";
                }
            }
    
            private void Webc_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
            {
                if (e.Error != null && !e.Cancelled)
                {
                    MessageBox.Show("下载时出现错误: " + e.Error.Message);
                    CanChange = true;
                    progressBar1.Value = 0;
                }
                else
                {
                    DownloadNext();
                }
            }
    
            private void Webc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
            {
                progressBar1.Value = progressBar1.Maximum - ((ToDownload.Count + 1) * 100) + e.ProgressPercentage;
            }
    
            Queue<int> ToDownload = new Queue<int>();
    
            private void DownloadNext()
            {
                if (ToDownload.Any())
                {
                    int nextId = ToDownload.Dequeue();
                    TaskDemo101.RunByWebClient(webc, nextId);
                    WhenSingleDownloaded(nextId, true);
                    progressBar1.Value = progressBar1.Maximum - ((ToDownload.Count + 1) * 100);
                }
                else
                {
                    MessageBox.Show("全部下载完成");
                    CanChange = true;
                    progressBar1.Value = 0;
                    btnRunByWebClient.Text = "用 WebClient 开始下载";
                    WhenAllDownloaded();
                }
            }
        }

    3. 运行截图

    如图:

    下载完成以后:

    谢谢浏览!

  • 相关阅读:
    CSP-S2019 退役记
    近期考试反思
    有关近期情况的总结与反思
    我好难啊
    AFO
    智障错误集锦
    关于博客密码【asd
    关于csp-s的各种问题整理
    CSP-S 临别赠言( 二 )
    分层图最短路 乱搞分享
  • 原文地址:https://www.cnblogs.com/Music/p/WebClient-DownloadFileAsync.html
Copyright © 2011-2022 走看看