2012-12-28 21 views
13

BenBant genişliği nasıl sınırlanır ve bir dosya indirilirken birden fazla indirmeye izin verilir?

using (System.IO.FileStream fs = System.IO.File.OpenRead(@"C:\HugeFile.GBD")) 
{ 
    using (System.IO.BinaryReader br = new System.IO.BinaryReader(fs)) 
    { 
     Response.AddHeader("Cache-control", "private"); 
     Response.AddHeader("Content-Type", "application/octet-stream"); 
     Response.AddHeader("Content-Length", fs.Length.ToString()); 
     Response.AddHeader("Content-Disposition", "filename=HugeFile.GBD"); 
     Response.Flush(); 
     float kbs = 20f; 

     while (fs.Position < fs.Length) 
     { 
      if (!Response.IsClientConnected) 
       break; 
      byte[] bytes = br.ReadBytes((int)Math.Truncate(1024 * kbs)); 
      char[] c = UTF8Encoding.Default.GetChars(bytes); 

      Response.Write(c, 0, c.Length); 


      Response.Flush(); 
      System.Threading.Thread.Sleep(1000); 
     } 
     Response.Flush(); 
    } 
} 

Ama iki eşzamanlı bağlantı yaparsanız (aynı tarayıcı üzerinde ikinci bir indirmeye başlamak) ikincisi yürütmüyor yalnızca 1 indirme bir anda çalışırken o çalışıyor, bu kodu var ilk bitirene kadar. Bir ileti veya hatayla bir görev sonuçlarını kullanarak

Response için Başlıkları eklerken ...

Ben bu yüzden aynı anda aynı tarayıcıda indirmeleri 2+ yürütebileceği nasıl yapabilirim?

+0

Belki bu bir [Görev] (http://msdn.microsoft.com/en-us/library/system.threading.tasks.taskfactory.startnew.aspx) yapmak ve ihtiyacınız olanları döndürme içine bakmak . Ayrıca, daha fazla örnek için [bu siteyi] ziyaret edebilirsiniz (http://www.codethinked.com/net-40-and-systemthreadingtasks). –

+0

Yanlış olabilirdim, ama bence bunun için multithread kullanmanız gerekmiyor. Sunucu otomatik olarak bununla başa çıkmalı, hatta büyük bir dosyadır. Nasıl test edersin? Ya 2 farklı makineden test ederse ve hala aynı sorunu varsa? – urlreader

+0

Görevler veya iş parçacıklarını kullanarak, Response.AddHeader ("Önbellek denetimi", "özel"); 'ArgumentException, Değer beklenen aralıkta düşmez. ' – BrunoLM

cevap

1

Google Chrome'un bir indirme işlemini benzersiz bir URL ile işlediği anlaşılıyor. Bu nedenle, aynı URL'ye erişmeye çalıştığımda, bu eylemi bile çalıştırmıyor. URL'ye, ex şey ekleyerek

:

home/download?x=1 
home/download?x=2 
home/download?x=3 

Krom farklı bir indirme olduğunu düşünüyorum ve bunu alacak. Yani, bir dosyayı indirmek için, her defasında farklı bir oluşturulmuş dosya olsa bile, URL'yi değiştirmemiz gerekir.

Ve

Ben FilePathResult devralan bir FileThrottleResult oluşturulan gaz gelince:

using System; 
using System.IO; 
using System.Threading; 
using System.Web.Mvc; 

namespace Mvc3Test 
{ 
    public class FileThrottleResult : FilePathResult 
    { 
     float rate = 0; 

     /// <summary> 
     /// 
     /// </summary> 
     /// <param name="fileName"></param> 
     /// <param name="contentType"></param> 
     /// <param name="rate">Kbps</param> 
     public FileThrottleResult(string fileName, string contentType, float rate) 
      : base(fileName, contentType) 
     { 
      if (!File.Exists(fileName)) 
      { 
       throw new ArgumentNullException("fileName"); 
      } 
      this.rate = rate; 
     } 

     protected override void WriteFile(System.Web.HttpResponseBase response) 
     { 
      int _bufferSize = (int)Math.Round(1024 * this.rate); 
      byte[] buffer = new byte[_bufferSize]; 

      Stream outputStream = response.OutputStream; 

      using (var stream = File.OpenRead(FileName)) 
      { 
       response.AddHeader("Cache-control", "private"); 
       response.AddHeader("Content-Type", "application/octet-stream"); 
       response.AddHeader("Content-Length", stream.Length.ToString()); 
       response.AddHeader("Content-Disposition", String.Format("filename={0}", new FileInfo(FileName).Name)); 
       response.Flush(); 

       while (true) 
       { 
        if (!response.IsClientConnected) 
         break; 

        int bytesRead = stream.Read(buffer, 0, _bufferSize); 
        if (bytesRead == 0) 
         break; 

        outputStream.Write(buffer, 0, bytesRead); 
        response.Flush(); 
        Thread.Sleep(1000); 
       } 
      } 
     } 
    } 
} 

Kullanımı: Bu başarıyla bant genişliğini sınırlar ve eşzamanlı indirme ile sorun olmaz

public FileThrottleResult Download() 
{ 
    string testFile = @"C:\hugefile.zip"; 
    return new FileThrottleResult(testFile, "application/octet-stream", 200); 
} 

Aynı dosya, tarayıcıyı "farklı" bir url ile kandıracağınız sürece.

İlgili konular