2012-06-04 27 views
5

मुझे अपने फ़ाइल डाउनलोडर एप्लिकेशन के लिए डाउनलोड दर सीमा लागू करने की आवश्यकता है, और मैंने कोडप्रोजेक्ट से ThrottledStream कक्षा को देखा है, लेकिन यह मेरे मामले में काम नहीं करेगा क्योंकि मुझे सक्षम होना है डाउनलोड के दौरान सीमा को बदलने के लिए, न केवल शुरुआत में।डाउनलोड प्रबंधक - डाउनलोड गति को सीमित करें

webResponse = (HttpWebResponse)webRequest.GetResponse(); 
responseStream = webResponse.GetResponseStream(); 
responseStream.ReadTimeout = 5000; 

downloadCache = new MemoryStream(this.MaxCacheSize); 
byte[] downloadBuffer = new byte[this.BufferSize]; 
int bytesSize = 0; 
CachedSize = 0; 
int receivedBufferCount = 0; 

while (true) 
{ 
    bytesSize = responseStream.Read(downloadBuffer, 0, downloadBuffer.Length); 

    if (this.Status != DownloadStatus.Downloading || bytesSize == 0 
     || this.MaxCacheSize < CachedSize + bytesSize) 
    { 
     WriteCacheToFile(downloadCache, CachedSize); 

     this.DownloadedSize += CachedSize; 
     downloadCache.Seek(0, SeekOrigin.Begin); 
     CachedSize = 0; 

     if (this.Status != DownloadStatus.Downloading || bytesSize == 0) 
      break; 
    } 

    downloadCache.Write(downloadBuffer, 0, bytesSize); 
    CachedSize += bytesSize; 

    receivedBufferCount++; 
    if (receivedBufferCount == this.BufferCountPerNotification) 
    { 
     this.RaiseDownloadProgressChanged(); 
     receivedBufferCount = 0; 
    } 
} 

मैं भी देखा लोगों Thread.Sleep() या Thread.Wait(), लेकिन यह एक अच्छा विचार है का उपयोग कर दिया है: यहाँ है कि मैं एक पृष्ठभूमि सूत्र में उपयोग कर रहा हूँ डाउनलोड विधि का एक हिस्सा है? क्या आपके पास कोई सुझाव है कि लूप के दौरान मैं इसे कैसे कर सकता हूं?

उत्तर

1

मैं सर्वर से फ़ाइलों को डाउनलोड करने के लिए यह आपके लिए उपयोगी है हो सकता है इस कोड का इस्तेमाल किया है ...

private bool DownLoadFile(string pstrFileName, string pstrFilePath, long plngFileSize) 
    { 
     try 
     { 
      string strNewFileSize = CalcFileSize(plngFileSize); 
      int numIterations = 0; // this is used with a modulus of the sampleInterval to check if the chunk size should be adjusted. it is started at 1 so that the first check will be skipped because it may involve an initial delay in connecting to the web service 
      Offset = 0; 
      long webConfigSetting = this.mobjService.GetMaxRequestLength(); 
      this.MaxRequestLength = Math.Max(1, (webConfigSetting * 1024) - (2 * 1024)); // set the max buffer size to slightly less than the request length to allow for SOAP message headers etc. 
      if (File.Exists(pstrFilePath)) 
      { 
       Offset = new FileInfo(pstrFilePath).Length; 
       if (Offset == plngFileSize) 
        Offset = 0; 
       //File.Delete(pstrFilePath); 
      } 
      if (Offset == 0 && !File.Exists(pstrFilePath)) // create a new empty file 
       File.Create(pstrFilePath).Close(); 

      // open a file stream for the file we will write to in the start-up folder 
      lblFileName.Text = pstrFileName.Substring(0, pstrFileName.LastIndexOf(".")).Replace("&", "&&"); 
      using (FileStream fs = new FileStream(pstrFilePath, FileMode.OpenOrCreate, FileAccess.Write)) 
      { 
       pbrSummary.Maximum = (int)plngFileSize; 
       fs.Seek(Offset, SeekOrigin.Begin); 
       // download the chunks from the web service one by one, until all the bytes have been read, meaning the entire file has been downloaded. 
       while (Offset < plngFileSize) 
       { 
        int currentIntervalMod = numIterations % this.ChunkSizeSampleInterval; 
        if (currentIntervalMod == 0) 
         StartTime = DateTime.Now; // used to calculate the time taken to transfer the first 5 chunks 
        else if (currentIntervalMod == 1) 
         CalcAndSetChunkSize(plngFileSize); 
        try 
        { 
         // although the DownloadChunk returns a byte[], it is actually sent using MTOM because of the configuration settings. 
         byte[] Buffer = mobjService.DownloadChunk(pstrFileName, Offset, ChunkSize); 
         fs.Write(Buffer, 0, Buffer.Length); 
         Offset += Buffer.Length; // save the offset position for resume 
        } 
        catch (Exception ex) 
        { 
         if (ex.Message.Contains("File not found") || NumRetries++ >= MaxRetries) // too many retries, bail out 
         { 
          fs.Close(); 
          return false; 
          //throw new Exception("Error occurred during upload, too many retries.\r\n" + ex.Message); 
         } 
        } 
        numIterations++; 
        //----------------------- Code Commented ------------------------ 
        //lblDownload.Text = CalcFileSize(Offset) + " of " + strNewFileSize; 
        //lblRate.Text = CalcFileSize(ChunkSize)+"/sec"; 
        ////pbrSummary.Value = (int)Offset; 
        ////if ((int)Offset <= pbrSummary.Maximum) 
        //// pbrSummary.Value = (int)Offset; 
        ////else 
        //// pbrSummary.Value = pbrSummary.Maximum; 
        //------------------------------------------------------------------ 
       } 
      } 
      return true; 
     } 
     catch (Exception Exc) 
     { 
      throw (Exc); 
     } 
    } 
    private void CalcAndSetChunkSize(long plngFileSize) 
    { 
     /* chunk size calculation is defined as follows 
     *  in the examples below, the preferred transfer time is 1500ms, taking one sample. 
     *  
     *         Example 1         Example 2 
     *  Initial size    = 16384 bytes (16k)      16384 
     *  Transfer time for 1 chunk = 800ms          2000 ms 
     *  Average throughput/ms  = 16384b/800ms = 20.48 b/ms    16384/2000 = 8.192 b/ms 
     *  How many bytes in 1500ms? = 20.48 * 1500 = 30720 bytes    8.192 * 1500 = 12228 bytes 
     *  New chunksize    = 30720 bytes (speed up)     12228 bytes (slow down from original chunk size) 
     */ 
     double transferTime = DateTime.Now.Subtract(this.StartTime).TotalMilliseconds; 
     double averageBytesPerMilliSec = this.ChunkSize/transferTime; 
     double preferredChunkSize = averageBytesPerMilliSec * this.PreferredTransferDuration; 
     this.ChunkSize = (int)Math.Min(this.MaxRequestLength, Math.Max(4 * 1024, preferredChunkSize)) * 10; // set the chunk size so that it takes 1500ms per chunk (estimate), not less than 4Kb and not greater than 4mb // (note 4096Kb sometimes causes problems, probably due to the IIS max request size limit, choosing a slightly smaller max size of 4 million bytes seems to work nicely)   

     //string statusMessage = String.Format("Chunk size: {0}{1}", CalcFileSize(this.ChunkSize), (this.ChunkSize == this.MaxRequestLength) ? " (max)" : ""); 
    } 
+0

मैं CalcFileSize विधि देखने की जरूरत – mehrdad