WebClient.DownloadFile(线程机制,异步下载文件)

      线程机制(避免卡屏),异步下载文件。

  我做网站的监控,WebClient.DownloadFile这个方法是我经常用到的,必要的时候肯定是要从网上下载些什么(WebRequest 也可以下载网络文件,不妨搜下,不过WebClient.DownloadFile使用更简单)。

 

  今天简单的演示下WebClient.DownloadFileAsync的使用,刚刚写好的实例,有问题你拍我。

  解释什么的都不需要了吧。这里面应用了线程机制,异步调用。wo先展示代码,在把一些关键点放置到后面,并给一些修改建议(设计器生成代码在下,可以不用看,只需要复制粘贴使用)。

测试中用到的网络文件(随机抽取.exe,.rar,.zip),都是无害的,请放心测试:

http://dl1sw.baidu.com/client/9h162/fzjqd.exe
http://sq.onlinedown.net/down/sgbs.rar
http://zj.down.chinaz.com/201408/bdswxt_v1.0.zip
http://zj.down.chinaz.com/201408/zyzfwxt_v1.1.zip

 

WebClient.DownloadFile(线程机制,异步下载文件)

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

using System.Net;

using System.Threading;

using System.IO;



namespace WindowsFormsApplication1

{

    public partial class Form1 : Form

    {

        public Form1()

        {

            InitializeComponent();



            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

        }



        static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)

        {

            File.AppendAllText(AppDomain.CurrentDomain.BaseDirectory + "error.log", DateTime.Now.ToString() + "\t" + e.ExceptionObject.ToString() + Environment.NewLine);

        }



        /// <summary>

        /// 文件总数

        /// </summary>

        int _totalFile = 0;

        /// <summary>

        /// 已下载文件

        /// </summary>

        int _loadFile = 0;



        private void button1_Click(object sender, EventArgs e)

        {//Run

            string richText = richTextBox1.Text;

            if (string.IsNullOrEmpty(richText))

            {

                MessageBox.Show("请在文本框中输入需要下载的网络文件");

            }



            Thread thread = new Thread(new ThreadStart(() => createWebClient(richText)));

            thread.Start();

        }



        //WebClient webClient = null;



        private void createWebClient(string richText)

        {

            string[] array = richText.Split(new string[] { "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);



            _totalFile = array.Length;



            foreach (string item in array)

            {

                WebClient webClient = new WebClient();



                webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(webClient_DownloadProgressChanged);

                webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(webClient_DownloadFileCompleted);



                string fileName = AppDomain.CurrentDomain.BaseDirectory + DateTime.Now.ToFileTimeUtc() + item.Substring(item.LastIndexOf('/') + 1);



                webClient.DownloadFileAsync(new Uri(item), fileName);



            }

        }



        private void webClient_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)

        {

            this.Invoke(new MethodInvoker(delegate {

                this.progressBar2.Value = e.ProgressPercentage;

                this.label2.Text = string.Format("正在下载文件,完成进度{0}%  {1}/{2}(字节)"

                                    ,e.ProgressPercentage

                                    , e.BytesReceived

                                    , e.TotalBytesToReceive);

             }));

        }



        private void webClient_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)

        {

            _loadFile++;



            int percent = (int)(100.0 * _loadFile / _totalFile);



            this.Invoke(new MethodInvoker(delegate {

                this.progressBar1.Value = percent;

                this.label1.Text = string.Format("已完成文件下载{0}%  {1}/{2}(文件个数)"

                    , percent

                    , _loadFile

                    , _totalFile);

            }));



            if (sender is WebClient)

            {

                ((WebClient)sender).CancelAsync();

                ((WebClient)sender).Dispose();

            }

        }



        private System.ComponentModel.IContainer components = null;

        protected override void Dispose(bool disposing)

        {

            if (disposing && (components != null))

            {

                components.Dispose();

            }

            base.Dispose(disposing);

        }

        private void InitializeComponent()

        {

            this.progressBar1 = new System.Windows.Forms.ProgressBar();

            this.progressBar2 = new System.Windows.Forms.ProgressBar();

            this.label1 = new System.Windows.Forms.Label();

            this.label2 = new System.Windows.Forms.Label();

            this.label3 = new System.Windows.Forms.Label();

            this.label4 = new System.Windows.Forms.Label();

            this.richTextBox1 = new System.Windows.Forms.RichTextBox();

            this.button1 = new System.Windows.Forms.Button();

            this.SuspendLayout();

            // 

            // progressBar1

            // 

            this.progressBar1.Location = new System.Drawing.Point(81, 160);

            this.progressBar1.Name = "progressBar1";

            this.progressBar1.Size = new System.Drawing.Size(330, 12);

            this.progressBar1.TabIndex = 0;

            // 

            // progressBar2

            // 

            this.progressBar2.Location = new System.Drawing.Point(81, 224);

            this.progressBar2.Name = "progressBar2";

            this.progressBar2.Size = new System.Drawing.Size(330, 12);

            this.progressBar2.TabIndex = 1;

            // 

            // label1

            // 

            this.label1.AutoSize = true;

            this.label1.Location = new System.Drawing.Point(59, 187);

            this.label1.Name = "label1";

            this.label1.Size = new System.Drawing.Size(41, 12);

            this.label1.TabIndex = 2;

            this.label1.Text = "label1";

            // 

            // label2

            // 

            this.label2.AutoSize = true;

            this.label2.Location = new System.Drawing.Point(59, 252);

            this.label2.Name = "label2";

            this.label2.Size = new System.Drawing.Size(41, 12);

            this.label2.TabIndex = 3;

            this.label2.Text = "label2";

            // 

            // label3

            // 

            this.label3.AutoSize = true;

            this.label3.Location = new System.Drawing.Point(12, 160);

            this.label3.Name = "label3";

            this.label3.Size = new System.Drawing.Size(65, 12);

            this.label3.TabIndex = 4;

            this.label3.Text = "总 进 度:";

            // 

            // label4

            // 

            this.label4.AutoSize = true;

            this.label4.Location = new System.Drawing.Point(12, 224);

            this.label4.Name = "label4";

            this.label4.Size = new System.Drawing.Size(65, 12);

            this.label4.TabIndex = 5;

            this.label4.Text = "当前进度:";

            // 

            // richTextBox1

            // 

            this.richTextBox1.Location = new System.Drawing.Point(14, 12);

            this.richTextBox1.Name = "richTextBox1";

            this.richTextBox1.Size = new System.Drawing.Size(397, 131);

            this.richTextBox1.TabIndex = 6;

            this.richTextBox1.Text = "";

            // 

            // button1

            // 

            this.button1.Location = new System.Drawing.Point(150, 280);

            this.button1.Name = "button1";

            this.button1.Size = new System.Drawing.Size(75, 23);

            this.button1.TabIndex = 7;

            this.button1.Text = "Run";

            this.button1.UseVisualStyleBackColor = true;

            this.button1.Click += new System.EventHandler(this.button1_Click);

            // 

            // Form1

            // 

            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);

            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;

            this.ClientSize = new System.Drawing.Size(423, 315);

            this.Controls.Add(this.button1);

            this.Controls.Add(this.richTextBox1);

            this.Controls.Add(this.label4);

            this.Controls.Add(this.label3);

            this.Controls.Add(this.label2);

            this.Controls.Add(this.label1);

            this.Controls.Add(this.progressBar2);

            this.Controls.Add(this.progressBar1);

            this.MaximumSize = new System.Drawing.Size(439, 353);

            this.MinimumSize = new System.Drawing.Size(439, 353);

            this.Name = "Form1";

            this.Text = "WebClient下载实现实例";

            this.ResumeLayout(false);

            this.PerformLayout();



        }

        private System.Windows.Forms.ProgressBar progressBar1;

        private System.Windows.Forms.ProgressBar progressBar2;

        private System.Windows.Forms.Label label1;

        private System.Windows.Forms.Label label2;

        private System.Windows.Forms.Label label3;

        private System.Windows.Forms.Label label4;

        private System.Windows.Forms.RichTextBox richTextBox1;

        private System.Windows.Forms.Button button1;

    }

}

 

 

大致看了一下,貌似就以下几句需要新手斟酌,大神请绕行。

第一句: this.Invoke(new MethodInvoker(delegate {

第二句:Thread thread = new Thread(new ThreadStart(() => createWebClient(richText)));

第三句:if (sender is WebClient)

 

第一句是关键的一句,不再创建控件的线程中调用/修改控件的属性值(Text),会报异常,为什么这么用就OK了?

第二句,第三句就简单了,不提示了,不会了找度度。

 

本程序可以添加的功能,添加一个Stop按钮,终断下载(请不要嗤之以鼻,在创建窗体的线程里操作new Thread让其立即终断下载,还是有点深度)

你可能感兴趣的:(download)