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,如需转载请自行联系原作者
目录
相关文章
|
26天前
|
数据采集 Java API
Jsoup库能处理多线程下载吗?
Jsoup库能处理多线程下载吗?
|
2月前
|
编解码 数据安全/隐私保护 计算机视觉
Opencv学习笔记(十):同步和异步(多线程)操作打开海康摄像头
如何使用OpenCV进行同步和异步操作来打开海康摄像头,并提供了相关的代码示例。
127 1
Opencv学习笔记(十):同步和异步(多线程)操作打开海康摄像头
|
4月前
|
数据采集 XML JavaScript
C# 中 ScrapySharp 的多线程下载策略
C# 中 ScrapySharp 的多线程下载策略
|
1月前
|
存储 监控 安全
深入理解ThreadLocal:线程局部变量的机制与应用
在Java的多线程编程中,`ThreadLocal`变量提供了一种线程安全的解决方案,允许每个线程拥有自己的变量副本,从而避免了线程间的数据竞争。本文将深入探讨`ThreadLocal`的工作原理、使用方法以及在实际开发中的应用场景。
61 2
|
2月前
lua面向对象(类)和lua协同线程与协同函数、Lua文件I/O
Lua的面向对象编程、协同线程与协同函数的概念和使用,以及Lua文件I/O操作的基本方法。
40 4
lua面向对象(类)和lua协同线程与协同函数、Lua文件I/O
|
1月前
|
Java
线程池内部机制:线程的保活与回收策略
【10月更文挑战第24天】 线程池是现代并发编程中管理线程资源的一种高效机制。它不仅能够复用线程,减少创建和销毁线程的开销,还能有效控制并发线程的数量,提高系统资源的利用率。本文将深入探讨线程池中线程的保活和回收机制,帮助你更好地理解和使用线程池。
92 2
|
2月前
|
Java
在Java多线程编程中,`wait()` 和 `notify()/notifyAll()` 方法是线程间通信的核心机制。
在Java多线程编程中,`wait()` 和 `notify()/notifyAll()` 方法是线程间通信的核心机制。它们通过基于锁的方式,使线程在条件不满足时进入休眠状态,并在条件成立时被唤醒,从而有效解决数据一致性和同步问题。本文通过对比其他通信机制,展示了 `wait()` 和 `notify()` 的优势,并通过生产者-消费者模型的示例代码,详细说明了其使用方法和重要性。
44 1
|
2月前
|
安全 Java 开发者
在多线程编程中,确保数据一致性与防止竞态条件至关重要。Java提供了多种线程同步机制
【10月更文挑战第3天】在多线程编程中,确保数据一致性与防止竞态条件至关重要。Java提供了多种线程同步机制,如`synchronized`关键字、`Lock`接口及其实现类(如`ReentrantLock`),还有原子变量(如`AtomicInteger`)。这些工具可以帮助开发者避免数据不一致、死锁和活锁等问题。通过合理选择和使用这些机制,可以有效管理并发,确保程序稳定运行。例如,`synchronized`可确保同一时间只有一个线程访问共享资源;`Lock`提供更灵活的锁定方式;原子变量则利用硬件指令实现无锁操作。
33 2
|
2月前
|
安全 调度 C#
STA模型、同步上下文和多线程、异步调度
【10月更文挑战第19天】本文介绍了 STA 模型、同步上下文和多线程、异步调度的概念及其优缺点。STA 模型适用于单线程环境,确保资源访问的顺序性;同步上下文和多线程提高了程序的并发性和响应性,但增加了复杂性;异步调度提升了程序的响应性和资源利用率,但也带来了编程复杂性和错误处理的挑战。选择合适的模型需根据具体应用场景和需求进行权衡。
|
2月前
|
网络协议 安全 Java
难懂,误点!将多线程技术应用于Python的异步事件循环
难懂,误点!将多线程技术应用于Python的异步事件循环
97 0