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

  我做网站的监控,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 = ;
/// <summary>
/// 已下载文件
/// </summary>
int _loadFile = ; 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('/') + ); 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(, );
this.progressBar1.Name = "progressBar1";
this.progressBar1.Size = new System.Drawing.Size(, );
this.progressBar1.TabIndex = ;
//
// progressBar2
//
this.progressBar2.Location = new System.Drawing.Point(, );
this.progressBar2.Name = "progressBar2";
this.progressBar2.Size = new System.Drawing.Size(, );
this.progressBar2.TabIndex = ;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(, );
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(, );
this.label1.TabIndex = ;
this.label1.Text = "label1";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(, );
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(, );
this.label2.TabIndex = ;
this.label2.Text = "label2";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(, );
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(, );
this.label3.TabIndex = ;
this.label3.Text = "总 进 度:";
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(, );
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(, );
this.label4.TabIndex = ;
this.label4.Text = "当前进度:";
//
// richTextBox1
//
this.richTextBox1.Location = new System.Drawing.Point(, );
this.richTextBox1.Name = "richTextBox1";
this.richTextBox1.Size = new System.Drawing.Size(, );
this.richTextBox1.TabIndex = ;
this.richTextBox1.Text = "";
//
// button1
//
this.button1.Location = new System.Drawing.Point(, );
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(, );
this.button1.TabIndex = ;
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(, );
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(, );
this.MinimumSize = new System.Drawing.Size(, );
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让其立即终断下载,还是有点深度)

WebClient.DownloadFile(线程机制,异步下载文件)的更多相关文章

  1. Web 端异步下载文件

    Web 端异步下载文件 实现文件异步下载: 在服务端无法返回文件,或发生异常时给予提示. JavaScript: 服务端返回的JSON对象形如: { code:200, msg:'下载成功|未找到指定 ...

  2. WebClient异步下载文件

    namespace ConsoleAppSyncDownload{    class Program    { static void Main(string[] args)        {     ...

  3. [c#]WebClient异步下载文件并显示进度

    摘要 在项目开发中经常会用到下载文件,这里使用winform实现了一个带进度条的例子. 一个例子 using System; using System.Collections.Generic; usi ...

  4. 使用webClient实现图片同步,异步下载

    WebClient.DownloadFile 方法 将具有指定 URI 的资源下载到本地文件. 命名空间:System.Net 程序集:System(在 system.dll 中) 同步实现参考代码: ...

  5. C# 异步下载文件

    在C#当中,利用WebClient这个核心类,可以轻易的打造一个下载器.但是这里想要强调的是,我们用的是异步操作.所谓异步,是相对于同步的概念而言的.比如Web中的Ajax就是基于异步的.它能够提供良 ...

  6. C# WebClient类上传和下载文件

    这篇文章主要介绍了C# WebClient类用法实例,本文讲解使用WebClient下载文件.OpenWriter打开一个流使用指定的方法将数据写入到uri以及上传文件示例,需要的朋友可以参考下   ...

  7. 主线程中一定不能放耗时操作,必须要开子线程,比如下载文件,不然会不让你拿到输入流--报错显示android.os.NetworkOnMainThreadException

    1.必须要开子线程来操作耗时操作,android.os.NetworkOnMainThreadException new Thread(new Runnable() { @Override publi ...

  8. js异步下载文件请求

    注意 :通常下载文件是用get请求 window.location.href=url; 但是 我们需要下载完成监听,所以必须要异步执行.用常规的ajax是不可以的.我们要用blob对象来实现1.原生的 ...

  9. android开发步步为营之67:使用android开源项目android-async-http异步下载文件

    android-async-http项目地址 https://github.com/loopj/android-async-http.android-async-http顾名思义是异步的http请求, ...

随机推荐

  1. 自话自说——POI使用需要注意一个地方

    2015.12.1  天气 不怎么好   心情跟天气一样.知道为什么吗,因为昨晚一晚没睡你懂吗... 今天在用POI操作excel的时候,遇到了一个很恶心的地方,这个地方真的有那种让我不相信编程的感觉 ...

  2. jquery 模拟 alert 手机,pc,平板 3合一

    $.kw = { title : "System information", //默认标题 可修改 speed : 400, //默认速度 可修改 buttonName : &qu ...

  3. JS动态级联菜单

    JS动态级联菜单是前端常用的一个功能,特此抽时间研究了下,附上代码 <html> <head> <meta charset="utf-8" /> ...

  4. DedeCMS织梦系统head.htm里无法调用栏目描述

    {dede:channel type='top'} [field:description/] {/dede:channel} channel 这个标签没有description属性你需要自己把这个属性 ...

  5. 对于新安装的MySQL如何提升MySQL的安全级别

    一 作为最流行的开源数据库引擎,MySQL本身是非常安全的.即便如此,你仍然需要添加额外的安全层来保护你的MySQL数据库不受攻击,毕竟任何经营网上在线业务的人都不想冒数据库受到损坏的风险.接下来,我 ...

  6. 如何为Eclipse安装主题(Color Theme)

    Eclipse开发环境默认都是白底黑字的,看到同事的Xcode中设置的黑灰色背景挺好看的,就去网上查了一下.发现Eclipse也可以设置主题. 方法1:你可以从Eclipse Marketplace中 ...

  7. K最短路 A*算法

    POJ2449 Remmarguts' Date #include <iostream> #include <algorithm> #include <queue> ...

  8. KMP 算法

    KMP 是一个字符串匹配算法.之所以称之为KMP 是因为这个算法是由Knuth.Morris.Pratt三个提出来的. 这个算法能干什么呢 ? 我想到的有三个: 1. 告诉你一个串是否是另外一个串的子 ...

  9. php中的mysql 和 mysqli 区别

    mysql是非持续连接函数,每次链接都会打开一个连接进程 mysqli是持续连接函数,多次运行将使用同一连接进程,从而降低服务器开销.

  10. 普通用户使用dbms_xplan包需要有的权限

    普通用户使用dbms_xplan包查看执行计划需要对v$sql.v$sql_plan.v$session及v$sql_plan_statistics_all这四个视图同时具有select权限. 如果普 ...