- 浏览: 244361 次
- 性别:
- 来自: 天津
文章分类
最新评论
-
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 1263项目中碰到了静态页文件读写冲突的问题(如果同时存在读写就报黄页 ... -
线程,同步与锁——Lock你到底锁住了谁
2011-04-03 14:59 778线程在多核时代的优势 ... -
多线程下WinForm开发应该注意哪些问题?
2011-04-03 14:52 946昨日,与一同事一起在 ... -
在多线程中如何调用Winform
2011-04-03 14:44 889转自 dengsu888666 每一 ... -
关于.NET异步调用的初步总结
2011-04-03 14:42 1005最近看了看.NET异步调用方面的资料,现择重点总结,若有纰漏敬 ... -
对 Windows 窗体控件进行线程安全调用
2011-04-03 14:39 919今天在编写一个windows应用程序的时候碰到了一个小问题,程 ... -
DotNet中异步编程的简单应用
2011-04-03 14:35 538这里说的异步编程并不是AJAX等的Web异步编程,而仅仅是Do ... -
winform程序中如何跨线程修改控件的值
2011-04-03 14:30 1624winform程序是单线程的。 /// <summar ... -
多线程执行多任务的DEMO
2011-04-03 14:21 919这个场景应用比较普遍, 比如多个线程下载多个文件,比如3个线程 ... -
生产者消费者线程在Queue中实现多线程同步
2011-04-03 14:19 2397使用C#进行多线程编程经常会用队列池进行线程同步的方法,实现就 ... -
.NET3.5下用Lambda简化跨线程访问窗体控件,避免繁复的delegate,Invoke
2011-04-03 14:06 12271,错误的代码是: using System; using ... -
利用委托机制处理.NET中的异常
2011-04-03 14:01 1138转自 terrylee.cnblogs.com 概述 在. ... -
线程安全类 跨线程修改窗体UI
2011-04-03 13:54 874private void ThreadSafeInvoke(C ...
相关推荐
在这个“C#多线程下载”的场景中,我们将深入探讨如何利用C#的WCF(Windows Communication Foundation)框架和多线程技术来实现文件的高效下载。 WCF是微软推出的一种面向服务的架构,用于构建和部署高度可互操作、...
综上所述,C#多线程下载文件涉及到了多线程编程、文件流操作、网络通信、同步控制、错误处理、异步编程等多个方面,是学习C#高级特性和实际应用的好例子。通过对提供的源码进行研究,开发者不仅可以掌握多线程下载的...
总的来说,C#多线程下载程序涉及了多线程编程、HTTP通信、文件I/O以及错误处理等多个重要知识点,是提升C#编程能力的一个实用案例。通过不断学习和优化,可以将这个基础的下载工具升级为一个功能完备、性能出色的...
总结来说,C#多线程下载工具通过`BackgroundWorker`或`Thread`实现了文件的并行下载,提高了下载速度和用户体验。在设计时,需要注意线程间的同步与通信,以及异常处理机制,确保程序的稳定性和可靠性。
本示例“C#多线程下载demo”旨在展示如何利用多线程来加速文件的下载过程。多线程允许程序同时执行多个任务,从而提高效率并改善用户体验。 首先,我们要理解C#中的线程。在.NET框架中,`System.Threading`命名空间...
本文将深入探讨如何利用C#实现多线程下载文件,并结合给出的"多线程下载文件"项目,理解其工作原理。 首先,让我们了解什么是多线程。线程是操作系统分配CPU时间的基本单元,一个进程中可以有多个线程同时执行。多...
完整开源的C#多线程下载工具,含源程序和可执行 DEMO,支持 Youtube 等视频网站视频的下载;优秀的插件机制,使得整个程序可扩展性极强。 架构清楚,代码整洁,不失为学习研究的好材料。 项目介绍主页:...
本文将深入探讨如何在C#中实现多线程下载文件,涉及的知识点包括线程池、异步编程、进度更新以及错误处理。 首先,我们需要了解线程的基本概念。在C#中,线程是程序执行的独立路径,每个线程都有自己的调用堆栈,...
在C#编程中,实现一个支持断点续传和多线程下载的HTTP Web客户端工具类是一项复杂但实用的任务。断点续传允许用户在下载过程中中断,然后在稍后的时间点继续下载,而不会丢失已下载的数据。多线程下载则能显著提高大...
在这个特定的场景中,我们讨论的是利用C#实现多线程下载功能,类似于迷你迅雷这样的下载管理器。迷你迅雷作为一个小型的下载工具,它能够通过创建多个下载任务并行地从网络获取数据,从而显著提高了文件下载速度。 ...
c# 多线程 下载 可以下载视频。歌曲。网页。。。。
在实际应用中,C#多线程下载类的实现还需要考虑以下几个方面: 1. **错误处理**:对于网络波动导致的下载中断,需要有重试机制,确保下载能够恢复并继续。 2. **断点续传**:如果下载过程中断,应该能够记录已下载...
在IT领域,多线程技术是提升程序性能和效率的重要手段,特别是在文件下载客户端中,多线程下载能够显著提高下载速度。本文将详细讲解基于C#和C++的多线程文件下载客户端的实现原理及关键技术。 首先,我们要理解...
以下是对这个“C#多线程文件下载程序”中涉及的关键知识点的详细解释: 1. **C#**: C#是一种面向对象的编程语言,由微软开发,主要用于.NET框架。它具有丰富的特性和强大的库支持,适用于开发各种类型的应用程序,...
C#实现的多线程下载程序代码,并用CRC进行校验。
本书是一本通俗易懂的C#多线程编程指南,通过70多个容易理解的示例,循序渐进地讲解C#5.0中的异步及并发编程,引导读者了解Windows下C#多线程编程的多样性。 通过阅读本书,你将学到: 使用原始线程、异步线程,...
本文将深入探讨如何使用C#语言来实现HTTP环境下的多线程下载功能,这对于处理大文件下载或者优化用户体验具有重要意义。 首先,我们要理解多线程的基本概念。在单线程程序中,任务是顺序执行的,而多线程允许同时...
本教程将探讨如何使用C#来实现多线程文件下载的实例,帮助开发者更好地理解和剖析项目源码,从而提升编程技能。 首先,理解多线程的概念至关重要。在单线程环境中,程序执行是顺序的,而多线程允许程序同时执行多个...
1. **C#多线程**: C#支持多线程编程,主要通过`System.Threading`命名空间中的类来实现。创建新线程的基本方法是使用`Thread`类的构造函数,或者使用`Task`类进行异步操作。多线程可以使程序并行执行多个任务,...
标题中的"C#多线程批量下载"涉及到的是在C#编程环境下,利用多线程技术进行文件批量下载的实现。这种技术通常用于提高文件下载效率,尤其是在处理大量文件或者大文件时,通过并发的方式可以显著减少整体的下载时间。...