【转】Asp.net 2.0 文件下载[支持多线程, 断点续传功能](示例代码下载)

【转】Asp.net 2.0 文件下载[支持多线程, 断点续传功能](示例代码下载)

(一) . 概述

        最近做了个C/S文件下载工具, 支持多任务, 多线程和断点续传功能. 其中部分代码是从网上找来的, 自己改了

许多Bug, 并增加断点续传等功能.  

        由于公司具有代码所有权, 不能将源代码共享.  自己对比较Asp.net感兴趣, 业余时间自己做了个简单的, 基于Asp.net 2.0的, 功能虽然不是很强大, 但已经实现了多线程, 断点续传功能.  分享一下, 互相学习!  互相借鉴!

              

(二).运行效果

 

(三). 代码

    1. 核心 DownLoadState.cs 文件代码

   1  ///  
   2  ///  Author: [ ChengKing(ZhengJian) ] 
   3  ///  Blog:   Http://blog.csdn.net/ChengKing
   4  ///  注:从网上找了个优秀代码
   5  ///  扩展如下功能: 
   6  ///    1. 解决一些线程相关的Bug; 
   7  ///    2.扩展用控制文件实现断点续传功能.
   8  ///  

   9  namespace  DownLoadComponent
  10  {
  11       ///  
  12       ///  多线程辅助类(Add by ChengKing)
  13       ///  

  14       public   class  Task
  15      {
  16           string  _FromFileName;
  17           string  _ToFileName;
  18           int  _ThreadNum;
  19 
  20           public  Task( string  FromFileName,  string  ToFileName,  int  ThreadNum)
  21          {
  22               this ._FromFileName  =  FromFileName;
  23               this ._ToFileName  =  ToFileName;
  24               this ._ThreadNum  =  ThreadNum;
  25          }
  26 
  27           public   string  FromFileName
  28          {
  29               get
  30              {
  31                   return  _FromFileName;
  32              }
  33               set
  34              {
  35                  _FromFileName  =  value;
  36              }
  37          }
  38           public   string  ToFileName
  39          {
  40               get
  41              {
  42                   return  _ToFileName;
  43              }
  44               set
  45              {
  46                  _ToFileName  =  value;
  47              }
  48          }
  49           public   int  ThreadNum
  50          {
  51               get
  52              {
  53                   return  _ThreadNum;
  54              }
  55               set
  56              {
  57                  _ThreadNum  =  value;
  58              }
  59          }
  60      }
  61 
  62       ///  
  63       ///  记录下载的字节位置
  64       ///  

  65       public   class  DownLoadState
  66      {
  67           private   string  _FileName;
  68 
  69           private   string  _AttachmentName;
  70           private   int  _Position;
  71           private   string  _RequestURL;
  72           private   string  _ResponseURL;
  73           private   int  _Length;
  74 
  75           private   byte [] _Data;
  76 
  77           public   string  FileName
  78          {
  79               get
  80              {
  81                   return  _FileName;
  82              }
  83          }
  84 
  85           public   int  Position
  86          {
  87               get
  88              {
  89                   return  _Position;
  90              }
  91          }
  92 
  93           public   int  Length
  94          {
  95               get
  96              {
  97                   return  _Length;
  98              }
  99          }
 100 
 101 
 102           public   string  AttachmentName
 103          {
 104               get
 105              {
 106                   return  _AttachmentName;
 107              }
 108          }
 109 
 110           public   string  RequestURL
 111          {
 112               get
 113              {
 114                   return  _RequestURL;
 115              }
 116          }
 117 
 118           public   string  ResponseURL
 119          {
 120               get
 121              {
 122                   return  _ResponseURL;
 123              }
 124          }
 125 
 126 
 127           public   byte [] Data
 128          {
 129               get
 130              {
 131                   return  _Data;
 132              }
 133          }
 134 
 135           internal  DownLoadState( string  RequestURL,  string  ResponseURL,  string  FileName,  string  AttachmentName,  int  Position,  int  Length,  byte [] Data)
 136          {
 137               this ._FileName  =  FileName;
 138               this ._RequestURL  =  RequestURL;
 139               this ._ResponseURL  =  ResponseURL;
 140               this ._AttachmentName  =  AttachmentName;
 141               this ._Position  =  Position;
 142               this ._Data  =  Data;
 143               this ._Length  =  Length;
 144          }
 145 
 146           internal  DownLoadState( string  RequestURL,  string  ResponseURL,  string  FileName,  string  AttachmentName,  int  Position,  int  Length, ThreadCallbackHandler tch)
 147          {
 148               this ._RequestURL  =  RequestURL;
 149               this ._ResponseURL  =  ResponseURL;
 150               this ._FileName  =  FileName;
 151               this ._AttachmentName  =  AttachmentName;
 152               this ._Position  =  Position;
 153               this ._Length  =  Length;
 154               this ._ThreadCallback  =  tch;
 155          }
 156 
 157           internal  DownLoadState( string  RequestURL,  string  ResponseURL,  string  FileName,  string  AttachmentName,  int  Position,  int  Length)
 158          {
 159               this ._RequestURL  =  RequestURL;
 160               this ._ResponseURL  =  ResponseURL;
 161               this ._FileName  =  FileName;
 162               this ._AttachmentName  =  AttachmentName;
 163               this ._Position  =  Position;
 164               this ._Length  =  Length;
 165          }
 166 
 167           private  ThreadCallbackHandler _ThreadCallback;
 168 
 169           //
 170           internal   void  StartDownloadFileChunk()
 171          {
 172               if  ( this ._ThreadCallback  !=   null )
 173              {
 174                   this ._ThreadCallback( this ._RequestURL,  this ._FileName,  this ._Position,  this ._Length);
 175              }
 176          }
 177 
 178      }
 179 
 180       // 委托代理线程的所执行的方法签名一致
 181       public   delegate   void  ThreadCallbackHandler( string  S,  string  s,  int  I,  int  i);
 182 
 183       // 异常处理动作
 184       public   enum  ExceptionActions
 185      {
 186          Throw,
 187          CancelAll,
 188          Ignore,
 189          Retry
 190      }
 191 
 192       ///  
 193       ///  包含 Exception 事件数据的类
 194       ///  

 195       public   class  ExceptionEventArgs : System.EventArgs
 196      {
 197           private  System.Exception _Exception;
 198           private  ExceptionActions _ExceptionAction;
 199 
 200           private  DownLoadState _DownloadState;
 201 
 202           public  DownLoadState DownloadState
 203          {
 204               get
 205              {
 206                   return  _DownloadState;
 207              }
 208          }
 209 
 210           public  Exception Exception
 211          {
 212               get
 213              {
 214                   return  _Exception;
 215              }
 216          }
 217 
 218           public  ExceptionActions ExceptionAction
 219          {
 220               get
 221              {
 222                   return  _ExceptionAction;
 223              }
 224               set
 225              {
 226                  _ExceptionAction  =  value;
 227              }
 228          }
 229 
 230           internal  ExceptionEventArgs(System.Exception e, DownLoadState DownloadState)
 231          {
 232               this ._Exception  =  e;
 233               this ._DownloadState  =  DownloadState;
 234          }
 235      }
 236 
 237       ///  
 238       ///  包含 DownLoad 事件数据的类
 239       ///  

 240       public   class  DownLoadEventArgs : System.EventArgs
 241      {
 242           private  DownLoadState _DownloadState;
 243 
 244           public  DownLoadState DownloadState
 245          {
 246               get
 247              {
 248                   return  _DownloadState;
 249              }
 250          }
 251 
 252           public  DownLoadEventArgs(DownLoadState DownloadState)
 253          {
 254               this ._DownloadState  =  DownloadState;
 255          }
 256 
 257      }
 258 
 259       ///  
 260       ///  支持断点续传多线程下载的类
 261       ///  

 262       public   class  HttpWebClient
 263      {
 264           private   static   object  _SyncLockObject  =   new   object ();
 265 
 266           public   delegate   void  DataReceiveEventHandler(HttpWebClient Sender, DownLoadEventArgs e);
 267 
 268           public   event  DataReceiveEventHandler DataReceive;  // 接收字节数据事件
 269 
 270           public   delegate   void  ExceptionEventHandler(HttpWebClient Sender, ExceptionEventArgs e);
 271 
 272           public   event  ExceptionEventHandler ExceptionOccurrs;  // 发生异常事件
 273 
 274           private   int  _FileLength;  // 下载文件的总大小
 275 
 276           public   static  ArrayList threads;
 277 
 278           public   int  FileLength
 279          {
 280               get
 281              {
 282                   return  _FileLength;
 283              }
 284          }
 285 
 286           ///  
 287           ///  分块下载文件
 288           ///  

 289           ///   URL 地址
 290           ///   保存到本地的路径文件名
 291           ///   块数,线程数
 292           public   void  DownloadFile( string  Address,  string  FileName,  int  ChunksCount)
 293          {
 294               int  p  =   0 //  position
 295               int  s  =   0 //  chunk size
 296               string  a  =   null ;
 297              HttpWebRequest hwrq;
 298              HttpWebResponse hwrp  =   null ;
 299               try
 300              {
 301 
 302                  hwrq  =  (HttpWebRequest)WebRequest.Create( this .GetUri(Address));
 303                   // hwrq.Timeout = 20000000;
 304                   // if (hwrq.HaveResponse == false)
 305                   //     return;
 306                   // hwrq.ProtocolVersion =HttpVersion.Version10;
 307                   // WebProxy wp = WebProxy.GetDefaultProxy();
 308                   // hwrq.Proxy = wp;
 309                  hwrq.Method  =   " GET " ;
 310                   try
 311                  {
 312                      hwrp  =  (HttpWebResponse)hwrq.GetResponse();
 313                  }
 314                   catch  (Exception e)
 315                  {
 316                       throw   new  Exception(e.Message);
 317                  }
 318 
 319                   long  L  =  hwrp.ContentLength;
 320 
 321                   // 如果文件太小, 就不用分多线程, 用一个线程下载即可. (目前控制在800K) 
 322                   // if (L < 800000)
 323                   // {
 324                   //     ChunksCount = 1;
 325                   // }
 326 
 327                  hwrq.Credentials  =   this .m_credentials;
 328 
 329                  L  =  ((L  ==   - 1 ||  (L  >   0x7fffffff ))  ?  (( long ) 0x7fffffff ) : L;  // Int32.MaxValue 该常数的值为 2,147,483,647; 即十六进制的 0x7FFFFFFF
 330 
 331                   int  l  =  ( int )L;
 332 
 333                   this ._FileLength  =  l;
 334 
 335                   bool  b  =  (hwrp.Headers[ " Accept-Ranges " !=   null   &  hwrp.Headers[ " Accept-Ranges " ==   " bytes " );
 336                  a  =  hwrp.Headers[ " Content-Disposition " ];  // attachment
 337                   if  (a  !=   null )
 338                  {
 339                      a  =  a.Substring(a.LastIndexOf( " filename= " +   9 );
 340                  }
 341                   else
 342                  {
 343                      a  =  FileName;
 344                  }
 345 
 346                   int  ss  =  s;
 347                   if  (b)
 348                  {
 349                       if  (ExistControlFile(FileName))  // 是否存在文件
 350                      {
 351                           string [] strBlocks  =   this .ReadInfFromControlFile(FileName).Split( new   char [ 2 ] {  ' \r ' ' \n '  });
 352                           for  ( int  i  =   0 ; i  <  strBlocks.Length; i ++ )
 353                          {
 354                               if  (strBlocks[i].Trim().Length  !=   0   &&  strBlocks[i].Substring(strBlocks[i].Length  -   1 ==   " 0 " )
 355                              {
 356                                   string [] strRecord  =  strBlocks[i].Split( ' , ' );
 357                                   int  p2  =   int .Parse(strRecord[ 0 ]);
 358                                   int  s2  =   int .Parse(strRecord[ 1 ]);
 359                                  DownLoadState x  =   new  DownLoadState(Address, hwrp.ResponseUri.AbsolutePath, FileName, a, p2, s2,  new  ThreadCallbackHandler( this .DownloadFileChunk));
 360                                  Thread t  =   new  Thread( new  ThreadStart(x.StartDownloadFileChunk));
 361                                   if  (threads  ==   null )
 362                                  {
 363                                      threads  =   new  ArrayList();
 364                                  }
 365                                  threads.Add(t);
 366                                  t.Start();
 367                              }
 368 
 369 
 370                          }
 371 
 372                      }
 373                       else
 374                      {
 375                           // 建立控制文件
 376                          FileStream fs  =  File.Create( this .GetControlFileName(FileName));
 377                          fs.Close();
 378 
 379                           if  (File.Exists(FileName))
 380                          {
 381                              FileInfo fi  =   new  FileInfo(FileName);
 382                               if  (fi.Length  ==  L)
 383                              {
 384                                   this .AddendInfToControlFile(FileName,  0 0 );
 385                                   this .UpdateControlFile(FileName,  0 0 );
 386                                   return ;
 387                              }
 388                          }
 389 
 390                          s  =  l  /  ChunksCount;
 391                           if  (s  <   2   *   64   *   1024 // 块大小至少为 128 K 字节
 392                          {
 393                              s  =   2   *   64   *   1024 ;
 394                          }
 395                          ss  =  s;
 396                           int  i  =   0 ;
 397                           while  (l  >=  s)
 398                          {
 399                              l  -=  s;
 400                               if  (l  <  s)
 401                              {
 402                                  s  +=  l;
 403                              }
 404                               if  (i ++   >   0 )
 405                              {
 406                                  DownLoadState x  =   new  DownLoadState(Address, hwrp.ResponseUri.AbsolutePath, FileName, a, p, s,  new  ThreadCallbackHandler( this .DownloadFileChunk));
 407 
 408                                  AddendInfToControlFile(FileName, p, s);
 409                                  Thread t  =   new  Thread( new  ThreadStart(x.StartDownloadFileChunk));
 410                                   if  (threads  ==   null )
 411                                  {
 412                                      threads  =   new  ArrayList();
 413                                  }
 414                                  threads.Add(t);
 415                                  t.Start();
 416 
 417                              }
 418                              p  +=  s;
 419                          }
 420                          s  =  ss;
 421 
 422                          AddendInfToControlFile(FileName,  0 , s);
 423                          DownLoadState x1  =   new  DownLoadState(Address, hwrp.ResponseUri.AbsolutePath, FileName, a,  0 , s,  new  ThreadCallbackHandler( this .DownloadFileChunk));
 424                          Thread t2  =   new  Thread( new  ThreadStart(x1.StartDownloadFileChunk));
 425                           if  (threads  ==   null )
 426                          {
 427                              threads  =   new  ArrayList();
 428                          }
 429                          threads.Add(t2);
 430                          t2.Start();
 431                      }
 432                  }
 433                   // 如果服务器不支持断点续传(Accept-Range), 则使用单线程下载
 434                   else
 435                  {
 436                      AddendInfToControlFile(FileName,  0 , l);
 437                      DownLoadState x  =   new  DownLoadState(Address, hwrp.ResponseUri.AbsolutePath, FileName, a,  0 , l,  new  ThreadCallbackHandler( this .DownloadFileChunk));
 438                      Thread t  =   new  Thread( new  ThreadStart(x.StartDownloadFileChunk));
 439                       if  (threads  ==   null )
 440                      {
 441                          threads  =   new  ArrayList();
 442                      }
 443                      threads.Add(t);
 444                      t.Start();
 445                  }
 446              }
 447               catch  (Exception e)
 448              {
 449                   // if (blnReturn == true)
 450                   // {
 451                   //     return;
 452                   // }
 453 
 454                  ExceptionActions ea  =  ExceptionActions.Throw;
 455                   if  (ea  ==  ExceptionActions.Throw)
 456                  {
 457                       if  ( ! (e  is  WebException)  &&   ! (e  is  SecurityException))
 458                      {
 459                           throw   new  WebException( " net_webclient " , e);
 460                      }
 461                       throw ;
 462                  }
 463 
 464 
 465                   // if (this.ExceptionOccurrs != null)
 466                   // {                    
 467                   //     DownLoadState x = new DownLoadState(Address, hwrp.ResponseUri.AbsolutePath, FileName, a, p, s);
 468 
 469                   //     ExceptionEventArgs eea = new ExceptionEventArgs(e, x);
 470                   //     ExceptionOccurrs(this, eea);
 471                   //     ea = eea.ExceptionAction;
 472                   // }
 473 
 474              }
 475 
 476          }
 477 
 478           #region  操作控制文件(By King Zheng)
 479 
 480           ///  
 481           ///  插入文件块信息到控制文件(Add by ChengKing)
 482           ///  

 483           ///  
 484           ///  
 485           ///  
 486           private   void  AddendInfToControlFile( string  FileName,  int  Position,  int  Length)
 487          {
 488 
 489 
 490               try
 491              {
 492                   lock  (_SyncLockObject)
 493                  {
 494                       string  strControlFile  =  GetControlFileName(FileName);
 495 
 496 
 497                       // if (File.Exists(strControlFile) == false)
 498                       // {
 499                       //     return;
 500                       // }
 501 
 502                       using  (StreamWriter sw  =   new  StreamWriter(strControlFile,  true , Encoding.Default))
 503                      {
 504                           // sw.NewLine = "$";
 505                          sw.WriteLine(Position.ToString()  +   " , "   +  Length.ToString()  +   " , "   +   " 0 " );
 506                      }
 507                       // using (System.IO.FileStream sw = new System.IO.FileStream(strControlFile, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.ReadWrite, System.IO.FileShare.ReadWrite))
 508                       // {
 509                       //      // sw.Position = e.DownloadState.Position;
 510                       //     sw.Write(Position.ToString() + "," + Length.ToString() + "," + "0"); 
 511                       //     sw.Close();
 512                       // }
 513 
 514 
 515 
 516                  }
 517              }
 518               catch  (Exception e)
 519              {
 520                   throw   new  Exception( " 写控制文件出错! "   +  e.Message);
 521              }
 522 
 523          }
 524 
 525           ///  
 526           ///  更新控制文件(Add by ChengKing)
 527           ///  

 528           ///  
 529           ///  
 530           ///  
 531           private   void  UpdateControlFile( string  FileName,  int  Position,  int  Length)
 532          {
 533               try
 534              {
 535                   lock  (_SyncLockObject)
 536                  {
 537                       string  strControlFile  =  GetControlFileName(FileName);
 538 
 539 
 540                       // if (File.Exists(strControlFile) == false)
 541                       // {
 542                       //     return;
 543                       // }
 544 
 545                       string  s  =   null ;
 546                       using  (StreamReader sr  =   new  System.IO.StreamReader(strControlFile))
 547                      {
 548                          s  =  sr.ReadToEnd();
 549                          s  =  s.Replace(Position.ToString()  +   " , "   +  Length.ToString()  +   " , "   +   " 0 " , Position.ToString()  +   " , "   +  Length.ToString()  +   " , "   +   " 1 " );
 550                      }
 551                       using  (StreamWriter sw  =   new  StreamWriter(strControlFile,  false , Encoding.Default))
 552                      {
 553                          sw.WriteLine(s);
 554                      }
 555                  }
 556              }
 557               catch  (Exception e)
 558              {
 559                   throw   new  Exception( " 更新控制文件出错! "   +  e.Message);
 560              }
 561 
 562          }
 563 
 564           ///  
 565           ///  读取所有信息从控制文件(Add by ChengKing)
 566           ///  

 567           ///  
 568           ///  
 569           private   string  ReadInfFromControlFile( string  FileName)
 570          {
 571               try
 572              {
 573                   lock  (_SyncLockObject)
 574                  {
 575                       string  strControlFile  =  GetControlFileName(FileName);
 576 
 577                       string  s  =   null ;
 578                       using  (StreamReader sr  =   new  System.IO.StreamReader(strControlFile))
 579                      {
 580                          s  =  sr.ReadToEnd();
 581 
 582                      }
 583                       return  s;
 584                  }
 585              }
 586               catch  (Exception e)
 587              {
 588                   throw   new  Exception( " 读控制文件出错! "   +  e.Message);
 589              }
 590          }
 591 
 592           ///  
 593           ///  根据目标文件名得到控制文件名(Add by ChengKing)
 594           ///  

 595           ///  
 596           ///  
 597           public   string  GetControlFileName( string  FileName)
 598          {
 599               string  strPath  =  Path.GetDirectoryName(FileName);
 600 
 601               // string strFileNameWithoutExtension = Path.GetFileNameWithoutExtension(FileName);
 602               string  strFileNameWithoutExtension  =  Path.GetFileName(FileName);
 603               string  strControlFile  =  Path.Combine(strPath, strFileNameWithoutExtension  +   " _Control.txt " );
 604               return  strControlFile;
 605          }
 606 
 607           ///  
 608           ///  判断控制文件是否存在
 609           ///  

 610           ///  
 611           ///  
 612           private   bool  ExistControlFile( string  FileName)
 613          {
 614               string  strControlFile  =  GetControlFileName(FileName);
 615               if  (File.Exists(strControlFile))
 616              {
 617                   return   true ;
 618              }
 619               return   false ;
 620          }
 621 
 622           ///  
 623           ///  判断控制文件是否完成
 624           ///  

 625           ///  
 626           ///  
 627           public   bool  JudgeControlFileIfFinished( string  strControlFile)
 628          {
 629               try
 630              {
 631                   string  s  =   null ;
 632                   lock  (_SyncLockObject)
 633                  {
 634                       using  (StreamReader sr  =   new  System.IO.StreamReader(strControlFile))
 635                      {
 636                          s  =  sr.ReadToEnd();
 637                      }
 638                  }
 639                   if  (s  +  String.Empty  ==  String.Empty)
 640                  {
 641                       return   false ;
 642                  }
 643                   string [] strBlocks  =  s.Split( new   char [ 2 ] {  ' \r ' ' \n '  });
 644                   for  ( int  i  =   0 ; i  <  strBlocks.Length; i ++ )
 645                  {
 646                       if  (strBlocks[i].Trim().Length  !=   0   &&  strBlocks[i].Substring(strBlocks[i].Length  -   1 ==   " 0 " )
 647                      {
 648                           return   false ;
 649                      }
 650                  }
 651                   return   true ;
 652 
 653              }
 654               catch  (Exception e)
 655              {
 656                   throw   new  Exception( " 判断控制文件是否完成时, 读取文件出错! "   +  e.Message);
 657              }
 658          }
 659 
 660           ///  
 661           ///  删除控制文件(Add by ChengKing)
 662           ///  

 663           ///  
 664           ///  
 665           public   bool  DeleteControlFile( string  strControlFile)
 666          {
 667               try
 668              {
 669                   lock  (_SyncLockObject)
 670                  {
 671                       if  (File.Exists(strControlFile))
 672                      {
 673                          File.Delete(strControlFile);
 674                      }
 675                  }
 676                   return   true ;
 677              }
 678               catch  (Exception e)
 679              {
 680                   throw   new  Exception( " 删除控制文件出错! "   +  e.Message);
 681              }
 682          }
 683 
 684           #endregion
 685 
 686           ///  
 687           ///  下载一个文件块,利用该方法可自行实现多线程断点续传
 688           ///  

 689           ///   URL 地址
 690           ///   保存到本地的路径文件名
 691           ///   块大小
 692           public   void  DownloadFileChunk( string  Address,  string  FileName,  int  FromPosition,  int  Length)
 693          {
 694              HttpWebResponse hwrp  =   null ;
 695               string  a  =   null ;
 696               try
 697              {
 698                   // this._FileName = FileName;
 699                  HttpWebRequest hwrq  =  (HttpWebRequest)WebRequest.Create( this .GetUri(Address));
 700                   // hwrq.Credentials = this.m_credentials;
 701 
 702                  hwrq.AddRange(FromPosition);
 703 
 704                  hwrp  =  (HttpWebResponse)hwrq.GetResponse();
 705 
 706                   // hwrp.Headers.Add("Content-Range", FromPosition.ToString());   // Test
 707 
 708                  a  =  hwrp.Headers[ " Content-Disposition " ];  // attachment
 709                   if  (a  !=   null )
 710                  {
 711                      a  =  a.Substring(a.LastIndexOf( " filename= " +   9 );
 712                  }
 713                   else
 714                  {
 715                      a  =  FileName;
 716                  }
 717 
 718                   byte [] buffer  =   this .ResponseAsBytes(Address, hwrp, Length, FileName);
 719                   //    lock (_SyncLockObject)
 720                   //    {
 721                   //     this._Bytes += buffer.Length;
 722                   //    }
 723              }
 724               catch  (Exception e)
 725              {
 726                  ExceptionActions ea  =  ExceptionActions.Throw;
 727                   if  ( this .ExceptionOccurrs  !=   null )
 728                  {
 729                      DownLoadState x  =   new  DownLoadState(Address, hwrp.ResponseUri.AbsolutePath, FileName, a, FromPosition, Length);
 730                      ExceptionEventArgs eea  =   new  ExceptionEventArgs(e, x);
 731                      ExceptionOccurrs( this , eea);
 732                      ea  =  eea.ExceptionAction;
 733                  }
 734 
 735                   if  (ea  ==  ExceptionActions.Throw)
 736                  {
 737                       if  ( ! (e  is  WebException)  &&   ! (e  is  SecurityException))
 738                      {
 739                           throw   new  WebException( " net_webclient " , e);
 740                      }
 741                       throw ;
 742                  }
 743              }
 744          }
 745 
 746           internal   byte [] ResponseAsBytes( string  RequestURL, WebResponse Response,  long  Length,  string  FileName)
 747          {
 748               string  a  =   null // AttachmentName
 749               int  P  =   0 // 整个文件的位置指针
 750               int  num2  =   0 ;
 751               int  num3  =   0 ;
 752               int  intFrom  =   0 ;
 753               try
 754              {
 755                  a  =  Response.Headers[ " Content-Disposition " ];  // attachment
 756                   if  (a  !=   null )
 757                  {
 758                      a  =  a.Substring(a.LastIndexOf( " filename= " +   9 );
 759                  }
 760 
 761                   long  num1  =  Length;  // Response.ContentLength;
 762                   bool  flag1  =   false ;
 763                   if  (num1  ==   - 1 )
 764                  {
 765                      flag1  =   true ;
 766                      num1  =   0x10000 // 64k
 767                  }
 768                   byte [] buffer1  =   new   byte [( long )num1];
 769 
 770 
 771                   int  p  =   0 // 本块的位置指针
 772 
 773                   string  s  =  Response.Headers[ " Content-Range " ];
 774                   // string s = hwrq.Headers["Range"];
 775 
 776                   if  (s  !=   null )
 777                  {
 778                      s  =  s.Replace( " bytes  " "" );
 779                      s  =  s.Substring( 0 , s.IndexOf( " - " ));
 780                      P  =  Convert.ToInt32(s);
 781                      intFrom  =  P;
 782 
 783                  }
 784 
 785                   // int num3 = 0;
 786 
 787                  Stream S  =  Response.GetResponseStream();
 788 
 789                   int  count  =   0 ;
 790 
 791                   int  bufferSize  =   65535 // 允许读取的最大字节
 792 
 793                   int  times;
 794                   do
 795                  {
 796                      times  =   0 ;
 797 
 798                       // num2 = S.Read(buffer1, num3, ((int)num1) - num3);
 799 
 800                       // 限制最大读取字节
 801                       if  (bufferSize  <  (( int )num1)  -  num3)
 802                      {
 803                          num2  =  S.Read(buffer1, num3, bufferSize);
 804                      }
 805                       else
 806                      {
 807                          num2  =  S.Read(buffer1, num3, (( int )num1)  -  num3);
 808                      }
 809 
 810                       // 网络短时间的不稳定
 811                       if  (num2  ==   0 )
 812                      {
 813                          Thread.Sleep( 50 );
 814                          times ++ ;
 815 
 816                           if  (times  >   100 )
 817                          {
 818                               throw   new  Exception( " 网络传输层错误 " );
 819                          }
 820 
 821                      }
 822 
 823                      num3  +=  num2;
 824                       if  (flag1  &&  (num3  ==  num1))
 825                      {
 826                          num1  +=   0x10000 ;
 827                           byte [] buffer2  =   new   byte [( int )num1];
 828                          Buffer.BlockCopy(buffer1,  0 , buffer2,  0 , num3);
 829                          buffer1  =  buffer2;
 830                      }
 831 
 832                       //     lock (_SyncLockObject)
 833                       //     {
 834                       //      this._bytes += num2;
 835                       //     }
 836                       if  (num2  >   0 )
 837                      {
 838                           if  ( this .DataReceive  !=   null )
 839                          {
 840                               byte [] buffer  =   new   byte [num2];
 841                              Buffer.BlockCopy(buffer1, p, buffer,  0 , buffer.Length);
 842                              DownLoadState dls  =   new  DownLoadState(RequestURL, Response.ResponseUri.AbsolutePath, FileName, a, P, num2, buffer);
 843                              DownLoadEventArgs dlea  =   new  DownLoadEventArgs(dls);
 844 
 845                               // 触发事件
 846                               this .OnDataReceive(dlea);
 847                               // System.Threading.Thread.Sleep(100);                            
 848 
 849                          }
 850                          p  +=  num2;  // 本块的位置指针
 851                          P  +=  num2;  // 整个文件的位置指针
 852                      }
 853                       else
 854                      {
 855                           break ;
 856                      }
 857 
 858                  }
 859                   while  (num2  !=   0 );
 860 
 861                  count ++ ;
 862 
 863                   int  c  =  count;
 864 
 865                  S.Close();
 866                  S  =   null ;
 867                   if  (flag1)
 868                  {
 869                       byte [] buffer3  =   new   byte [num3];
 870                      Buffer.BlockCopy(buffer1,  0 , buffer3,  0 , num3);
 871                      buffer1  =  buffer3;
 872                  }
 873 
 874                  UpdateControlFile(FileName, intFrom, ( int )Length);
 875 
 876                   return  buffer1;
 877              }
 878               catch  (Exception e)
 879              {
 880                  ExceptionActions ea  =  ExceptionActions.Throw;
 881                   if  ( this .ExceptionOccurrs  !=   null )
 882                  {
 883                      Thread.Sleep( 100 );
 884                       // DownLoadState x = new DownLoadState(RequestURL, Response.ResponseUri.AbsolutePath, FileName, a, P, num2);
 885                       // DownLoadState x = new DownLoadState(RequestURL, Response.ResponseUri.AbsolutePath, FileName, a, P, (int)(Length - num3));
 886                      DownLoadState x  =   new  DownLoadState(RequestURL, Response.ResponseUri.AbsolutePath, FileName, a, P, ( int )Length);
 887 
 888                      ExceptionEventArgs eea  =   new  ExceptionEventArgs(e, x);
 889                      ExceptionOccurrs( this , eea);
 890                      ea  =  eea.ExceptionAction;
 891                  }
 892 
 893                   if  (ea  ==  ExceptionActions.Throw)
 894                  {
 895                       if  ( ! (e  is  WebException)  &&   ! (e  is  SecurityException))
 896                      {
 897                           throw   new  WebException( " net_webclient " , e);
 898                      }
 899                       throw ;
 900                  }
 901                   return   null ;
 902              }
 903          }
 904 
 905           private   void  OnDataReceive(DownLoadEventArgs e)
 906          {
 907               // 触发数据到达事件
 908              DataReceive( this , e);
 909          }
 910 
 911           public   byte [] UploadFile( string  address,  string  fileName)
 912          {
 913               return   this .UploadFile(address,  " POST " , fileName,  " file " );
 914          }
 915 
 916           public   string  UploadFileEx( string  address,  string  method,  string  fileName,  string  fieldName)
 917          {
 918               return  Encoding.ASCII.GetString(UploadFile(address, method, fileName, fieldName));
 919          }
 920 
 921           public   byte [] UploadFile( string  address,  string  method,  string  fileName,  string  fieldName)
 922          {
 923               byte [] buffer4;
 924              FileStream stream1  =   null ;
 925               try
 926              {
 927                  fileName  =  Path.GetFullPath(fileName);
 928                   string  text1  =   " --------------------- "   +  DateTime.Now.Ticks.ToString( " x " );
 929 
 930                   string  text2  =   " application/octet-stream " ;
 931 
 932                  stream1  =   new  FileStream(fileName, FileMode.Open, FileAccess.Read);
 933                  WebRequest request1  =  WebRequest.Create( this .GetUri(address));
 934                  request1.Credentials  =   this .m_credentials;
 935                  request1.ContentType  =   " multipart/form-data; boundary= "   +  text1;
 936 
 937                  request1.Method  =  method;
 938                   string [] textArray1  =   new   string [ 7 ] {  " -- " , text1,  " \r\nContent-Disposition: form-data; name=\ ""  + fieldName +  " \ " ; filename=\ "" , Path.GetFileName(fileName),  " \ " \r\nContent-Type:  " , text2,  " \r\n\r\n "  };
 939                   string  text3  =   string .Concat(textArray1);
 940                   byte [] buffer1  =  Encoding.UTF8.GetBytes(text3);
 941                   byte [] buffer2  =  Encoding.ASCII.GetBytes( " \r\n-- "   +  text1  +   " \r\n " );
 942                   long  num1  =   0x7fffffffffffffff ;
 943                   try
 944                  {
 945                      num1  =  stream1.Length;
 946                      request1.ContentLength  =  (num1  +  buffer1.Length)  +  buffer2.Length;
 947                  }
 948                   catch
 949                  {
 950                  }
 951                   byte [] buffer3  =   new   byte [Math.Min( 0x2000 , ( int )num1)];
 952                   using  (Stream stream2  =  request1.GetRequestStream())
 953                  {
 954                       int  num2;
 955                      stream2.Write(buffer1,  0 , buffer1.Length);
 956                       do
 957                      {
 958                          num2  =  stream1.Read(buffer3,  0 , buffer3.Length);
 959                           if  (num2  !=   0 )
 960                          {
 961                              stream2.Write(buffer3,  0 , num2);
 962                          }
 963                      }
 964                       while  (num2  !=   0 );
 965                      stream2.Write(buffer2,  0 , buffer2.Length);
 966                  }
 967                  stream1.Close();
 968                  stream1  =   null ;
 969                  WebResponse response1  =  request1.GetResponse();
 970 
 971                  buffer4  =   this .ResponseAsBytes(response1);
 972              }
 973               catch  (Exception exception1)
 974              {
 975                   if  (stream1  !=   null )
 976                  {
 977                      stream1.Close();
 978                      stream1  =   null ;
 979                  }
 980                   if  ( ! (exception1  is  WebException)  &&   ! (exception1  is  SecurityException))
 981                  {
 982                       // throw new WebException(SR.GetString("net_webclient"), exception1);
 983                       throw   new  WebException( " net_webclient " , exception1);
 984                  }
 985                   throw ;
 986              }
 987               return  buffer4;
 988          }
 989 
 990           private   byte [] ResponseAsBytes(WebResponse response)
 991          {
 992               int  num2;
 993               long  num1  =  response.ContentLength;
 994               bool  flag1  =   false ;
 995               if  (num1  ==   - 1 )
 996              {
 997                  flag1  =   true ;
 998                  num1  =   0x10000 ;
 999              }
1000               byte [] buffer1  =   new   byte [( int )num1];
1001              Stream stream1  =  response.GetResponseStream();
1002               int  num3  =   0 ;
1003               do
1004              {
1005                  num2  =  stream1.Read(buffer1, num3, (( int )num1)  -  num3);
1006                  num3  +=  num2;
1007                   if  (flag1  &&  (num3  ==  num1))
1008                  {
1009                      num1  +=   0x10000 ;
1010                       byte [] buffer2  =   new   byte [( int )num1];
1011                      Buffer.BlockCopy(buffer1,  0 , buffer2,  0 , num3);
1012                      buffer1  =  buffer2;
1013                  }
1014              }
1015               while  (num2  !=   0 );
1016              stream1.Close();
1017               if  (flag1)
1018              {
1019                   byte [] buffer3  =   new   byte [num3];
1020                  Buffer.BlockCopy(buffer1,  0 , buffer3,  0 , num3);
1021                  buffer1  =  buffer3;
1022              }
1023               return  buffer1;
1024          }
1025 
1026           private  NameValueCollection m_requestParameters;
1027           private  Uri m_baseAddress;
1028           private  ICredentials m_credentials  =  CredentialCache.DefaultCredentials;
1029 
1030           public  ICredentials Credentials
1031          {
1032               get
1033              {
1034                   return   this .m_credentials;
1035              }
1036               set
1037              {
1038                   this .m_credentials  =  value;
1039              }
1040          }
1041 
1042           public  NameValueCollection QueryString
1043          {
1044               get
1045              {
1046                   if  ( this .m_requestParameters  ==   null )
1047                  {
1048                       this .m_requestParameters  =   new  NameValueCollection();
1049                  }
1050                   return   this .m_requestParameters;
1051              }
1052               set
1053              {
1054                   this .m_requestParameters  =  value;
1055              }
1056          }
1057 
1058           public   string  BaseAddress
1059          {
1060               get
1061              {
1062                   if  ( this .m_baseAddress  !=   null )
1063                  {
1064                       return   this .m_baseAddress.ToString();
1065                  }
1066                   return   string .Empty;
1067              }
1068               set
1069              {
1070                   if  ((value  ==   null ||  (value.Length  ==   0 ))
1071                  {
1072                       this .m_baseAddress  =   null ;
1073                  }
1074                   else
1075                  {
1076                       try
1077                      {
1078                           this .m_baseAddress  =   new  Uri(value);
1079                      }
1080                       catch  (Exception exception1)
1081                      {
1082                           throw   new  ArgumentException( " value " , exception1);
1083                      }
1084                  }
1085              }
1086          }
1087 
1088           public  Uri GetUri( string  path)
1089          {
1090              Uri uri1;
1091               try
1092              {
1093                   if  ( this .m_baseAddress  !=   null )
1094                  {
1095                      uri1  =   new  Uri( this .m_baseAddress, path);
1096                  }
1097                   else
1098                  {
1099                      uri1  =   new  Uri(path);
1100                  }
1101                   if  ( this .m_requestParameters  ==   null )
1102                  {
1103                       return  uri1;
1104                  }
1105                  StringBuilder builder1  =   new  StringBuilder();
1106                   string  text1  =   string .Empty;
1107                   for  ( int  num1  =   0 ; num1  <   this .m_requestParameters.Count; num1 ++ )
1108                  {
1109                      builder1.Append(text1  +   this .m_requestParameters.AllKeys[num1]  +   " = "   +   this .m_requestParameters[num1]);
1110                      text1  =   " & " ;
1111                  }
1112                  UriBuilder builder2  =   new  UriBuilder(uri1);
1113                  builder2.Query  =  builder1.ToString();
1114                  uri1  =  builder2.Uri;
1115              }
1116               catch  (UriFormatException)
1117              {
1118                  uri1  =   new  Uri(Path.GetFullPath(path));
1119              }
1120               return  uri1;
1121          }
1122 
1123      }
1124 
1125  }
1126 
1127 

    2.页面 Default.aspx 文件 代码

 1  < html xmlns = " http://www.w3.org/1999/xhtml "   >
 2  < head runat = " server " >
 3       < script language = " javascript " >
 4          mainLoop  =  function()
 5          {
 6              var objPath  =  document.getElementById( " TextBox2 " ); 
 7              var blnValue  =  _Default.CheckControlFiles(objPath.value);                       
 8               // a.value = a.value + blnValue.value;
 9               if ( blnValue.value  ==   true )
10              {
11                  var returnvalue = setTimeout( ' mainLoop() ' 1000 );            
12              }
13               else
14              {
15                  var objStatus  =  document.getElementById( " Label1 " ); 
16                  objStatus.innerText  =   " 状态: 下载完成! " ;
17                  
18                  var btOK  =  document.getElementById( " btOK " );
19                  btOK.disabled  =   "" ;              
20                  
21                  var btCancel  =  document.getElementById( " btCancel " );
22                  btCancel.disabled  =   " disabled " ;
23                                  
24              }
25          }    
26          
27      
28       script >
29 
30  head >
31  < body >
32       < form id = " frmTest "  runat = " server "   >
33       < table bgcolor = " #ffcc66 " >< tr >< td style = " height: 259px " >
34           < br  />
35           < strong >< span style = " color: #000099 " >
36          下载组件:
37           < br  />
38           1 . 支持多线程:  & nbsp;多个线程某时刻下载同一个文件的不同块. < br  />
39           2 . 断点续传:  & nbsp;如果下载了一个文件的某些块(一半), 则下次 < br  />
40               & nbsp;  & nbsp;  & nbsp;  & nbsp;  & nbsp;  & nbsp;  & nbsp;  & nbsp;  & nbsp;  & nbsp;  & nbsp; 下载时只需下载未完成的块;
41               & nbsp;文件块的下载状 < br  />
42               & nbsp;  & nbsp;  & nbsp;  & nbsp;  & nbsp;  & nbsp;  & nbsp;  & nbsp;  & nbsp;  & nbsp;  & nbsp; 态用控制文件记录.
43              块下载完成的先后顺序不 < br  />
44               & nbsp;  & nbsp;  & nbsp;  & nbsp;  & nbsp;  & nbsp;  & nbsp;  & nbsp;  & nbsp;  & nbsp;  & nbsp; 一定是连续的. < br  />
45           span > strong >
46           < br  />
47           < table style = " width: 379px " >
48               < tr >
49                   < td colspan = " 1 "  style = " width: 87px " >
50                      Source td >
51                   < td colspan = " 2 "  style = " width: 326px " >
52           < asp:TextBox ID = " TextBox1 "  runat = " server "  Width = " 391px " > http: // www.
53               tr >
54               < tr >
55                   < td colspan = " 1 "  style = " width: 87px " >
56                      Location td >
57                   < td colspan = " 2 "  style = " width: 326px " >
58                       < asp:TextBox ID = " TextBox2 "  runat = " server "  Width = " 391px " > D:\Documents and Settings\zhengjian\桌面\TestDownLoads\ asp:TextBox > td >
59               tr >
60               < tr >
61                   < td colspan = " 1 "  style = " width: 87px " >
62                      Threads td >
63                   < td colspan = " 2 "  style = " width: 326px " >
64                       < asp:TextBox ID = " TextBox3 "  runat = " server "  Width = " 390px " > 10 asp:TextBox > td >
65               tr >
66           table >
67           < br  />
68           < asp:Button ID = " btOK "  runat = " server "  Text = " 下载 "  Height = " 42px "  Width = " 108px "  OnClick = " btOK_Click "   />& nbsp;
69           & nbsp; < asp:Button ID = " btCancel "  runat = " server "  OnClick = " btCancel_Click "  Text = " 取消/暂停 "  Height = " 42px "  Width = " 108px "  Enabled = " False "   />< br  />
70           < br  />
71           < asp:Label ID = " Label1 "  runat = " server "  Height = " 32px "  Text = " 状态: 未开始下载 "  Width = " 227px "  Font - Bold = " True "  ForeColor = " #8080FF " > asp:Label >< br  />
72           td > tr > table >
73           < script language = javascript >
74              mainLoop();
75           script >
76       form >
77  body >
78  html >

   3. 页面后台文件 Default.aspx.cs代码

  1  ///  
  2  ///  Author: [ ChengKing(ZhengJian) ] 
  3  ///  Blog:   Http://blog.csdn.net/ChengKing
  4  ///  注:从网上找了个优秀代码
  5  ///  扩展如下功能: 
  6  ///    1. 解决一些线程相关的Bug; 
  7  ///    2.扩展用控制文件实现断点续传功能.
  8  ///  

  9  public  partial  class  _Default : System.Web.UI.Page 
 10  {    
 11       // 全局变量
 12       private   static   object  _SyncLockObject  =   new   object ();
 13 
 14       protected   void  Page_Load( object  sender, EventArgs e)
 15      {
 16          Utility.RegisterTypeForAjax( typeof (_Default));       
 17           // this.TextBox1.Text = " http://download.csdn.net/filedown/aHR0cDovL2Rvd25sb2FkMS5jc2RuLm5ldC9kb3duMy8yMDA3MDUwNy8wNzE4MDIwNzY4OC5yYXI= !177258";
 18          
 19          
 20           this .TextBox1.Text  =   " http://files.cnblogs.com/ChengKing/智能象棋游戏(T1).rar " ;
 21      }
 22       protected   void  btOK_Click( object  sender, EventArgs e)
 23      {
 24           this .Label1.Text  =   " 状态: 正在下载 " ;
 25          
 26          DownLoadComponent.HttpWebClient x  =   new  DownLoadComponent.HttpWebClient();
 27 
 28           // 注册 DataReceive 事件
 29          x.DataReceive  +=   new  DownLoadComponent.HttpWebClient.DataReceiveEventHandler( this .x_DataReceive);
 30           // 注册 ExceptionOccurrs 事件
 31          x.ExceptionOccurrs  +=   new  DownLoadComponent.HttpWebClient.ExceptionEventHandler( this .x_ExceptionOccurrs);
 32 
 33           string  Source  =   this .TextBox1.Text.Trim();
 34           string  FileName  =  Source.Substring(Source.LastIndexOf( " / " +   1 );
 35           string  Location =  System.IO.Path.Combine(  this .TextBox2.Text.Trim() , FileName);
 36          
 37           // F: 源服务器文件;  _f: 保存路径;  10: 自设定一个文件有几个线程下载.
 38          x.DownloadFile(Source,Location ,  int .Parse( this .TextBox3.Text));
 39 
 40           // Response.Write("正在下载文件");
 41           this .btOK.Enabled  =   false ;
 42           this .btCancel.Enabled  =   true ;
 43      }
 44 
 45       private   void  x_DataReceive(DownLoadComponent.HttpWebClient Sender, DownLoadComponent.DownLoadEventArgs e)
 46      {
 47 
 48           string  f  =  e.DownloadState.FileName;
 49           if  (e.DownloadState.AttachmentName  !=   null )
 50              f  =  System.IO.Path.GetDirectoryName(f)  +   @" \ "   +  e.DownloadState.AttachmentName;       
 51          
 52           using  (System.IO.FileStream sw  =   new  System.IO.FileStream(f, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.ReadWrite, System.IO.FileShare.ReadWrite))
 53          {
 54              sw.Position  =  e.DownloadState.Position;                
 55              sw.Write(e.DownloadState.Data,  0 , e.DownloadState.Data.Length); 
 56              sw.Close();
 57          }            
 58      }   
 59 
 60       private   void  x_ExceptionOccurrs(DownLoadComponent.HttpWebClient Sender, DownLoadComponent.ExceptionEventArgs e)
 61      {
 62          System.Console.WriteLine(e.Exception.Message);
 63           // 发生异常重新下载相当于断点续传,你可以自己自行选择处理方式或自行处理
 64          DownLoadComponent.HttpWebClient x  =   new  DownLoadComponent.HttpWebClient();
 65          x.DataReceive  +=   new  DownLoadComponent.HttpWebClient.DataReceiveEventHandler( this .x_DataReceive);
 66           // 订阅 ExceptionOccurrs 事件
 67           // x.ExceptionOccurrs += new DownLoadComponent.HttpWebClient.ExceptionEventHandler(this.x_ExceptionOccurrs);
 68 
 69          x.DownloadFileChunk(e.DownloadState.RequestURL, e.DownloadState.FileName, e.DownloadState.Position, e.DownloadState.Length);
 70          e.ExceptionAction  =  DownLoadComponent.ExceptionActions.Ignore;
 71      }
 72       protected   void  btCancel_Click( object  sender, EventArgs e)
 73      {
 74           if  (DownLoadComponent.HttpWebClient.threads  !=   null )
 75          {
 76               foreach  (Thread t  in  DownLoadComponent.HttpWebClient.threads)
 77              {
 78                   if  (t.IsAlive)
 79                  {
 80                      t.Abort();
 81                  }
 82              }
 83 
 84              DownLoadComponent.HttpWebClient.threads.Clear();
 85          }
 86          System.Diagnostics.Process myproc  =   new  System.Diagnostics.Process();
 87          Process[] procs  =  (Process[])Process.GetProcessesByName( " DW20.exe " );   // 得到所有打开的进程
 88           try
 89          {
 90               foreach  (Process proc  in  procs)
 91              {
 92                   if  (proc.CloseMainWindow()  ==   false )
 93                  {
 94                      proc.Kill();
 95                  }
 96              }
 97          }
 98           catch
 99          { }
100          KillAllThreads();
101           this .btOK.Enabled  =   true ;
102           this .btCancel.Enabled  =   false ;
103          GC.Collect();
104         
105      }
106 
107       ///  
108       ///  定期检查控制文件
109       ///  

110       ///  
111       ///   是否还继续监视(1: 正在下载中,继续监视; 0: 表示已经下载完毕,不用再检视)
112      [AjaxMethod()] //  or [AjaxPro.AjaxMethod] 
113       public   bool  CheckControlFiles( string  strObjPath)
114      {
115           if  ( ! WhetherDownloadFinished(strObjPath))
116          {
117               return   true ;
118          }
119           return   false ;
120      }
121 
122       private   bool  WhetherDownloadFinished( string  strObjPath)
123      {
124          DirectoryInfo df  =   new  DirectoryInfo(strObjPath);
125          FileInfo[] fi  =  (FileInfo[])df.GetFiles( " *.txt " , SearchOption.TopDirectoryOnly);
126          HttpWebClient hwc  =   new  HttpWebClient();        
127           for  ( int  i  =   0 ; i  <  fi.Length; i ++ )
128          {
129               if  (fi[i].FullName.Length  >   12   &&  fi[i].FullName.Substring(fi[i].FullName.Length  -   12 ==   " _Control.txt " )
130              {                
131                   if  (hwc.JudgeControlFileIfFinished(fi[i].FullName)  ==   true )
132                  {
133                      hwc.DeleteControlFile(fi[i].FullName);
134                      KillAllThreads();
135                       return   true ;
136                  }
137              }
138          }
139           return   false ;
140      }
141 
142       private   void  KillAllThreads()
143      {
144           foreach  (Thread t  in  HttpWebClient.threads)
145          {
146               if  (t.IsAlive)
147              {
148                  t.Abort();
149              }
150          }
151          HttpWebClient.threads.Clear();
152      }
153 
154  }
155 

 

(四).示例代码下载

       http://files.cnblogs.com/MVP33650/MultiThreadDownLoadFile.rar

(五).Asp.net 2.0其它相关文章:     

           http://blog.csdn.net/ChengKing/category/288694.aspx

posted on 2007-06-22 11:16 ms_dos 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/nine425/archive/2007/06/22/792846.html

你可能感兴趣的:(【转】Asp.net 2.0 文件下载[支持多线程, 断点续传功能](示例代码下载))