2012-12-28 16 views
13

मैं इस कोड है, कि जब केवल 1 डाउनलोड एक समय में चल रहा हैबैंडविड्थ को कैसे सीमित करें और फ़ाइल डाउनलोड करते समय एकाधिक डाउनलोड की अनुमति दें?

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(); 
    } 
} 

लेकिन अगर मैं दो एक साथ कनेक्शन बनाने (एक ही ब्राउज़र पर एक दूसरे डाउनलोड शुरू) दूसरा एक निष्पादित नहीं करता है काम कर रहा है पहले खत्म होने तक।

एक धागा या कोई त्रुटि में एक कार्य के परिणाम का उपयोग करते हुए जब Response के हेडर को जोड़ने ...

मैं इसे तो मैं 2 + डाउनलोड एक ही ब्राउज़र पर एक ही समय में निष्पादित कर सकते हैं कर सकते हैं कैसे?

+0

शायद इसे एक ['कार्य'] (http://msdn.microsoft.com/en-us/library/system.threading.tasks.taskfactory.startnew.aspx) बनाने और आपको आवश्यकतानुसार कताई करने में देखें । इसके अलावा, आप अधिक उदाहरणों के लिए [इस साइट] (http://www.codethinked.com/net-40-and-systemthreadingtasks) देख सकते हैं। –

+0

मैं गलत हो सकता था, लेकिन मुझे लगता है कि आपको इसके लिए मल्टीथ्रेड का उपयोग करने की आवश्यकता नहीं है। सर्वर को स्वचालित रूप से इससे निपटना चाहिए, भले ही यह एक बड़ी फाइल है। आप इसका परीक्षण कैसे करते हैं? क्या होगा यदि वे इसे 2 अलग मशीनों से परीक्षण करते हैं और फिर भी एक ही समस्या है? – urlreader

+0

कार्यों या धागे का उपयोग करके, यह 'Response.AddHeader ("कैश-कंट्रोल", "निजी") में विफल रहता है; ' ' ArgumentException, मान अपेक्षित सीमा के भीतर नहीं आता है। ' – BrunoLM

उत्तर

1

ऐसा लगता है कि Google क्रोम एक अद्वितीय यूआरएल के साथ एक डाउनलोड को संभालता है, इसलिए जब मैं एक ही यूआरएल तक पहुंचने का प्रयास करता हूं तो यह कार्रवाई भी नहीं चलाता है।

, पूर्व यूआरएल के लिए कुछ भी जोड़ कर:

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

क्रोम लगता है कि यह एक अलग डाउनलोड है और यह मिल जाएगा। इसलिए, फ़ाइल डाउनलोड करने के लिए, भले ही एक अलग जेनरेट की गई फ़ाइल हर बार, हमें यूआरएल को बदलने की जरूरत है।

और थ्रोटल के लिए के रूप में मैं एक FileThrottleResult जो FilePathResult से विरासत बनाया:

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); 
       } 
      } 
     } 
    } 
} 

उपयोग:

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

यह सफलतापूर्वक बैंडविड्थ सीमित कर देगा और के एक साथ डाउनलोड के साथ समस्या नहीं होगी एक ही फ़ाइल, जब तक आप ब्राउज़र को "अलग" यूआरएल के साथ चालित करते हैं।

संबंधित मुद्दे