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

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
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让其立即终断下载,还是有点深度)










本文转自 yuanzhitang 51CTO博客,原文链接:http://blog.51cto.com/yuanzhitang/1949842,如需转载请自行联系原作者
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值