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

 

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讓其立即終斷下載,還是有點深度)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM