- 浏览: 235990 次
- 性别:
- 来自: 天津
文章分类
最新评论
-
yulanlian:
...
实现在删除数据后,自增列的值连续 -
RonQi:
楼主写的很好,支持原创!
Google Protocol Buffers
下面是一个完整的多线程下载源码,我在写代码的时候遇到点问题也放在下面,希望大家别犯相同的错误。
问题1、线程偷懒?
在程序中我设置N个线程去下载时,然而有的线程却偷懒去了,当时非常奇怪,花了很多时间在代码上。
这其实是因为服务器不支持多线程下载造成的,大部分专业的下载站都禁止多线程下载,既然是服务器的原因那就没法了,在这里我想提一下在IIS7中启用和禁止多线程的方法。
应用程序池 -》 右击属性“高级设置” -》 进程模型 -》 最大工作进程数(这里便是设置允许多少线程)
至于IIS6也在应用程序池里设置,应用程序池- 》右击属性 -》 性能 -》 最大工作进程数。好了废话不说了,看下面的源码:
使用:
JhxzThreading mt = new JhxzThreading(5, "下载地址", "本地保存路径"); mt.FileName = "wenjian"; //保存的文件名 mt.Start();
JhxzThreading公开了一些属性方便调用,如IsComplete表示这个下载任务是否完成,还有DownloadSize这个是实时下载了多少字节,通过这两个我们可以很容易实现进度条。如果有进度控件par:
pbar.Maximum = (int)mt.FileSize; while (!mt.IsComplete) { pbar.Value = mt.DownloadSize; }
上面虽然实现进度条了,但是由于主线程一直在循环的工作,窗体可能会有假死现象,针对这个原因我们专门用一个线程来控制进度。于是有了下面的做法。
pbar.Maximum = (int)mt.FileSize; Thread bar = new Thread(() => { while (!mt.IsComplete) { Thread.Sleep(50); this.SafeInvoke(() => { pbar.Value = mt.DownloadSize; }); } MessageBox.Show("恭喜!文件已下载完成","提示",MessageBoxButtons.OK,MessageBoxIcon.Information); }); bar.Start();
如果对this.SafeInvoke有疑问点这里
http://hi.baidu.com/guigangsky/blog/item/dc831f126d542a56f919b828.html
多线程下载类:
using System.Net; using System.IO; using System.Collections.Generic; using System.Threading; using System; public class JhxzThreading { private int _threadNum; //线程数量 private long _fileSize; //文件大小 private string _extName; //文件扩展名 private string _fileUrl; //文件地址 private string _fileName; //文件名 private string _savePath; //保存路径 private short _threadCompleteNum; //线程完成数量 private bool _isComplete; //是否完成 private volatile int _downloadSize; //当前下载大小 private Thread[] _thread; //线程数组 private List<string> _tempFiles = new List<string>(); public string FileName { get { return _fileName; } set { _fileName = value; } } public long FileSize { get { return _fileSize; } } public int DownloadSize { get { return _downloadSize; } } public bool IsComplete { get { return _isComplete; } set { _isComplete = value; } } public int ThreadNum { get { return _threadNum; } set { _threadNum = value; } } public string SavePath { get { return _savePath; } set { _savePath = value; } } public JhxzThreading(int threahNum, string fileUrl, string savePath) { this._threadNum = threahNum; this._thread = new Thread[threahNum]; this._fileUrl = fileUrl; this._savePath = savePath; } public void Start() { HttpWebRequest request = (HttpWebRequest) WebRequest.Create(_fileUrl); HttpWebResponse response = (HttpWebResponse) request.GetResponse(); _extName = response.ResponseUri.ToString().Substring(response.ResponseUri.ToString().LastIndexOf('.'));//获取真实扩展名 _fileSize = response.ContentLength; int singelNum = (int) (_fileSize / _threadNum); //平均分配 int remainder = (int) (_fileSize % _threadNum); //获取剩余的 request.Abort(); response.Close(); for (int i = 0; i < _threadNum; i++) { List<int> range = new List<int>(); range.Add(i * singelNum); if (remainder != 0 && (_threadNum - 1) == i) //剩余的交给最后一个线程 range.Add(i * singelNum + singelNum + remainder - 1); else range.Add(i * singelNum + singelNum - 1); _thread[i] = new Thread(() => { Download(range[0], range[1]); }); _thread[i].Name = "jhxz_{0}".Formart(i + 1); _thread[i].Start(); } } private void Download(int from, int to) { Stream httpFileStream = null, localFileStram = null; try { string tmpFileBlock = @"{0}\{1}_{2}.dat".Formart(_savePath, _fileName, Thread.CurrentThread.Name); _tempFiles.Add(tmpFileBlock); HttpWebRequest httprequest = (HttpWebRequest) WebRequest.Create(_fileUrl); httprequest.AddRange(from, to); HttpWebResponse httpresponse = (HttpWebResponse) httprequest.GetResponse(); httpFileStream = httpresponse.GetResponseStream(); localFileStram = new FileStream(tmpFileBlock, FileMode.Create); byte[] by = new byte[5000]; int getByteSize = httpFileStream.Read(by, 0, (int) by.Length); //Read方法将返回读入by变量中的总字节数 while (getByteSize > 0) { Thread.Sleep(20); _downloadSize += getByteSize; localFileStram.Write(by, 0, getByteSize); getByteSize = httpFileStream.Read(by, 0, (int) by.Length); } _threadCompleteNum++; } catch (Exception ex) { throw new Exception(ex.Message.ToString()); } finally { if (httpFileStream != null) httpFileStream.Dispose(); if (localFileStram != null) localFileStram.Dispose(); } if (_threadCompleteNum == _threadNum) { _isComplete = true; Complete(); } } private void Complete() { Stream mergeFile = new FileStream(@"{0}\{1}{2}".Formart(_savePath, _fileName, _extName), FileMode.Create); BinaryWriter AddWriter = new BinaryWriter(mergeFile); foreach (string file in _tempFiles) { using (FileStream fs = new FileStream(file, FileMode.Open)) { BinaryReader TempReader = new BinaryReader(fs); AddWriter.Write(TempReader.ReadBytes((int) fs.Length)); TempReader.Close(); } File.Delete(file); } AddWriter.Close(); } }
发表评论
-
文件读写冲突的解决办法:ReaderWriterLock
2011-04-07 14:59 1215项目中碰到了静态页文件读写冲突的问题(如果同时存在读写就报黄页 ... -
线程,同步与锁——Lock你到底锁住了谁
2011-04-03 14:59 738线程在多核时代的优势 ... -
多线程下WinForm开发应该注意哪些问题?
2011-04-03 14:52 901昨日,与一同事一起在 ... -
在多线程中如何调用Winform
2011-04-03 14:44 858转自 dengsu888666 每一 ... -
关于.NET异步调用的初步总结
2011-04-03 14:42 974最近看了看.NET异步调用方面的资料,现择重点总结,若有纰漏敬 ... -
对 Windows 窗体控件进行线程安全调用
2011-04-03 14:39 876今天在编写一个windows应用程序的时候碰到了一个小问题,程 ... -
DotNet中异步编程的简单应用
2011-04-03 14:35 502这里说的异步编程并不是AJAX等的Web异步编程,而仅仅是Do ... -
winform程序中如何跨线程修改控件的值
2011-04-03 14:30 1567winform程序是单线程的。 /// <summar ... -
多线程执行多任务的DEMO
2011-04-03 14:21 877这个场景应用比较普遍, 比如多个线程下载多个文件,比如3个线程 ... -
生产者消费者线程在Queue中实现多线程同步
2011-04-03 14:19 2353使用C#进行多线程编程经常会用队列池进行线程同步的方法,实现就 ... -
.NET3.5下用Lambda简化跨线程访问窗体控件,避免繁复的delegate,Invoke
2011-04-03 14:06 11781,错误的代码是: using System; using ... -
利用委托机制处理.NET中的异常
2011-04-03 14:01 1099转自 terrylee.cnblogs.com 概述 在. ... -
线程安全类 跨线程修改窗体UI
2011-04-03 13:54 831private void ThreadSafeInvoke(C ...
相关推荐
C#多线程下载文件源码测试通过,而且值得参考,源码易懂易用适合二次开发
C# 多线程下载工具使用backgroundworker和thread实现
利用C#WCF框架和多线程下载文件,此程序为从服务端下载的示例
C# 多线程下载文件 下载即可运行 vs05.
C#多线程下载demo
C#多线程下载文件工具,可添加多任务,带断点续传功能
c#多线程下载源码,类似迷你迅雷的下载。包含实例
完整开源的C#多线程下载工具,含源程序和可执行 DEMO,支持 Youtube 等视频网站视频的下载;优秀的插件机制,使得整个程序可扩展性极强。 架构清楚,代码整洁,不失为学习研究的好材料。 项目介绍主页:...
C# winform开发,支持断点续传,程序写的不怎么好,有些bug
c# 多线程 下载 可以下载视频。歌曲。网页。。。。
C#多线程下载C#多线程下载C#多线程下载C#多线程下载C#多线程下载C#多线程下载C#多线程下载
c# 多线程文件下载程序
C#实现的多线程下载程序代码,并用CRC进行校验。
本书是一本通俗易懂的C#多线程编程指南,通过70多个容易理解的示例,循序渐进地讲解C#5.0中的异步及并发编程,引导读者了解Windows下C#多线程编程的多样性。 通过阅读本书,你将学到: 使用原始线程、异步线程,...
C#实现多线程下载文件,结合多线程技术的各方面知识,是比较好的学习例子。
多线程文件下载客户端
C# 多线程基本于httpwebrequest实现的下载功能 每个线程均可以通过事件追踪情况
串口通信的实现,编程环境为C#,实现技术采用了多线程方式
C#多线程下载类,C#模仿迅雷的多线程下载类
C#多线程互斥实例 多线程获取同一变量(不重复)。是一个很好的学习例子