multi-download files 多线程下载

using System;
using System.Net;
using System.ComponentModel;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace Downloader
{
    
class Program
    {
        
static void Main(string[] args)
        {
            List
<string> uriList = new List<string>();

            
#region init data
            uriList.Add(
"http://t1.gstatic.com/images?q=tbn:lJZx9zTCrSd9hM:");
            
//add more here
            
#endregion

            
//multi-download
            Stopwatch sw = new Stopwatch();
            sw.Start();
            DownloaderOlder oldMDownloader 
= new DownloaderOlder();
            oldMDownloader.DownloadFilesCompleted 
+= delegate
            {
                sw.Stop();
                Console.WriteLine(
"ok:" + sw.ElapsedMilliseconds);
                Console.ReadLine();
            };
            oldMDownloader.Download(uriList);

            
//single-download
            Stopwatch sw1 = new Stopwatch();
            sw1.Start();
            oldMDownloader.DownloadSingle(uriList);
            sw1.Stop();
            Console.WriteLine(
"ok2:{0},{1}", sw1.ElapsedMilliseconds, sw1.ElapsedMilliseconds / sw.ElapsedMilliseconds);

            
//multi-download client can set the max-thread count
            Stopwatch sw2 = new Stopwatch();
            sw2.Start();
            MultiDownloader mdownloader 
= new MultiDownloader(uriList);
            mdownloader.MaxThreadCount 
= 100;
            mdownloader.DownloadFilesCompleted 
+= delegate
            {
                sw2.Stop();
                Console.WriteLine(
"ok3:{0}", sw2.ElapsedMilliseconds);
                Console.ReadLine();
            };
            mdownloader.Start();

            Console.ReadLine();
        }
    }

    
public class DownloaderOlder
    {
        
public event AsyncCompletedEventHandler DownloadFilesCompleted;

        
private int TotalCount = 0;
        
private int count = 0;
        
public void Download(List<string> uriList)
        {
            TotalCount 
= uriList.Count;

            
foreach (var uri in uriList)
            {
                Download(uri);
            }
        }

        
public void DownloadSingle(List<string> uriList)
        {
            
foreach (var uri in uriList)
            {
                
string file = string.Format(@"d:\asy{0}.jpg",uri.GetHashCode());

                WebClient client 
= new WebClient();
                client.DownloadFile(uri, file);

            }
        }

        
public void Download(string uri)
        {
            
string file = string.Format(@"d:\{0}.jpg",uri.GetHashCode());
            
            WebClient client 
= new WebClient();
            client.DownloadFileCompleted 
+= new AsyncCompletedEventHandler(onCompleted);
            client.DownloadFileAsync(
new Uri(uri), file);
            
        }

        
public void onCompleted(object sender,AsyncCompletedEventArgs e)
        {           
            count
++;
            
if (count == TotalCount)
            {
                AsyncCompletedEventArgs args 
=new AsyncCompletedEventArgs(null,false,null);
                DownloadFilesCompleted.Invoke(
this, args);
            }
            
        }

        
    }

    
public class MultiDownloader
    {
        
public event AsyncCompletedEventHandler DownloadFilesCompleted;
        
public int MaxThreadCount { getset; }
        
private int _CurrentThreadCount = 0;

        
private int _TotalCount = 0;
        
private int _DownloadedCount = 0;
        
private Queue<Uri> _DownloadQueue = new Queue<Uri>();

        
public bool CanStartThread
        {
            
get 
            {
                
if (_DownloadQueue.Count == 0)
                    
return false;

                
if (_CurrentThreadCount == MaxThreadCount)
                    
return false;

                
return true;
            }
        }

        
public bool DownloadCompleted
        {
            
get { return _DownloadedCount == _TotalCount; }
        }
        

        
public MultiDownloader(List<string> uriList)
        {
            MaxThreadCount 
= 5;
            _TotalCount 
= uriList.Count;

            
foreach (var strURI in uriList)
                _DownloadQueue.Enqueue(
new Uri(strURI));
        }

        
public void Start()
        {
            
while (CanStartThread)
            {
                Uri uri 
= null;
                
lock (_DownloadQueue)
                {
                    uri 
= _DownloadQueue.Dequeue();
                }

                
if (uri == null)
                    
continue;

                
string file = string.Format(@"d:\{0}.jpg", uri.GetHashCode());

                WebClient client 
= new WebClient();
                client.DownloadFileCompleted 
+= new AsyncCompletedEventHandler(onCompleted);
                client.DownloadFileAsync(uri, file);
            }
        }

        
public void onCompleted(object sender, AsyncCompletedEventArgs e)
        {
            _DownloadedCount
++;

            
if (DownloadCompleted)
            {
                AsyncCompletedEventArgs args 
= new AsyncCompletedEventArgs(nullfalsenull);
                DownloadFilesCompleted.Invoke(
this, args);
                
return;
            }

            Start();

        }
        
       
    }
}

 

posted @ 2010-06-23 13:51  高天蒲  阅读(1107)  评论(4编辑  收藏  举报
[url=http://t.sina.com.cn/1084588625?s=6uyXnP][img]http://service.t.sina.com.cn/widget/qmd/1084588625/a57ab42b/1.png[/img][/url]