2013-03-07 43 views
0

請幫我一起穿線。我試圖下載一個文件,同時更新BTProgressHUD進度顯示。我知道它不工作的原因是使用主線程下載並且不允許我更新UI,但我無法解決如何正確使用線程池以允許我更新BTProgressHUD,文件正在下載。請幫忙!!單線穿線問題 - 在下載文件時更新BTProgressHUD

`

   BTProgressHUD.Show("Downloading...", progress); 
       string this_file = "example.pdf"; 

       string file_url = "http://our_server.com/files/" + this_file; 
       Uri url = new Uri(file_url); 

       var documents = Environment.GetFolderPath (Environment.SpecialFolder.MyDocuments); 
       var folder = Path.Combine (documents, "", "PDF"); 

       System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(url); 
       System.Net.HttpWebResponse response = (System.Net.HttpWebResponse)request.GetResponse(); 
       response.Close(); 

       Int64 iSize = response.ContentLength; 

       // keeps track of the total bytes downloaded so we can update the progress bar 
       Int64 iRunningByteTotal = 0; 

       // use the webclient object to download the file 
       using (System.Net.WebClient client = new System.Net.WebClient()) 
       { 
        // open the file at the remote URL for reading 
        using (System.IO.Stream streamRemote = client.OpenRead(new Uri(file_url))) 
        { 
         // using the FileStream object, we can write the downloaded bytes to the file system 
         using (Stream streamLocal = new FileStream(folder + "/" + this_file, FileMode.Create, FileAccess.Write, FileShare.None)) 
         { 

          // loop the stream and get the file into the byte buffer 
          int iByteSize = 0; 
          byte[] byteBuffer = new byte[iSize]; 
          while ((iByteSize = streamRemote.Read(byteBuffer, 0, byteBuffer.Length)) > 0) 
          { 
           // write the bytes to the file system at the file path specified 
           streamLocal.Write(byteBuffer, 0, iByteSize); 
           iRunningByteTotal += iByteSize; 

           // calculate the progress out of a base "100" 
           double dIndex = (double)(iRunningByteTotal); 
           double dTotal = (double)byteBuffer.Length; 
           double dProgressPercentage = (dIndex/dTotal); 
           int iProgressPercentage = (int)(dProgressPercentage * 100); 

           if (iProgressPercentage == 100) 
           { 

            var z = new UIAlertView ("Download Complete", this_file + " downloaded.", null, "OK", null); 
            z.Show(); 


            BTProgressHUD.Dismiss();            
           } 

           if (iProgressPercentage % 10 == 0) 
           { 
            // THIS BUT NEVER HAPPENS!!! Cannot update the progress display 
            progress += 0.1f; 
            BTProgressHUD.Show("XXX", progress); 
           } 

          } // while.. 

          streamLocal.Close(); // clean up the file stream 

         } // using stream 

         streamRemote.Close(); // close the connection to the remote server 

        } // using I.O 

       } // using system.net 

`

任何幫助將是非常非常感謝。

回答

1

我已經使用TPL來踢背景線程,然後通過使用InvokeOnMainThread回調到UI。我用一個UILabel替代了BTProgressHUD,但它的工作原理應該是一樣的。這是它的工作:

private void DownloadCoffeePDF() 
    { 
     Task.Factory.StartNew (() => { 
      InvokeOnMainThread(() => { 
       this.TheLabel.Text = string.Format("Downloading...{0}", progress); 
      }); 
      string file_url = "http://www.pnf.org/coffeeedited041001.pdf"; 
      Uri url = new Uri(file_url); 

      var documents = Environment.GetFolderPath (Environment.SpecialFolder.MyDocuments); 
      var folder = Path.Combine (documents, "", "PDF"); 

      System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(url); 
      System.Net.HttpWebResponse response = (System.Net.HttpWebResponse)request.GetResponse(); 
      response.Close(); 

      Int64 iSize = response.ContentLength; 

      // keeps track of the total bytes downloaded so we can update the progress bar 
      Int64 iRunningByteTotal = 0; 

      // use the webclient object to download the file 
      using (System.Net.WebClient client = new System.Net.WebClient()) 
      { 
       // open the file at the remote URL for reading 
       using (System.IO.Stream streamRemote = client.OpenRead(new Uri(file_url))) 
       { 
        // using the FileStream object, we can write the downloaded bytes to the file system 
        using (Stream streamLocal = new FileStream(folder + "/" + "Coffee.pdf", FileMode.Create, FileAccess.Write, FileShare.None)) 
        { 

         // loop the stream and get the file into the byte buffer 
         int iByteSize = 0; 
         byte[] byteBuffer = new byte[iSize]; 
         while ((iByteSize = streamRemote.Read(byteBuffer, 0, byteBuffer.Length)) > 0) 
         { 
          // write the bytes to the file system at the file path specified 
          streamLocal.Write(byteBuffer, 0, iByteSize); 
          iRunningByteTotal += iByteSize; 

          // calculate the progress out of a base "100" 
          double dIndex = (double)(iRunningByteTotal); 
          double dTotal = (double)byteBuffer.Length; 
          double dProgressPercentage = (dIndex/dTotal); 
          int iProgressPercentage = (int)(dProgressPercentage * 100); 

          if (iProgressPercentage == 100) 
          { 
            InvokeOnMainThread(() => { 
            var z = new UIAlertView ("Download Complete", "Coffee.pdf" + " downloaded.", null, "OK", null); 
            z.Show(); 


            this.TheLabel.Text = "Download Complete"; 
           }); 
          } 

          if (iProgressPercentage % 10 == 0) 
          { 
           InvokeOnMainThread(() => { 
           // THIS BUT NEVER HAPPENS!!! Cannot update the progress display 
            progress += 0.1f; 
            this.TheLabel.Text = string.Format("{0}", progress); 
           }); 
          } 

         } // while.. 

         streamLocal.Close(); // clean up the file stream 

        } // using stream 

        streamRemote.Close(); // close the connection to the remote server 

       } // using I.O 

      } // using system.net 
     }); 
    } 
+0

感謝您的幫助!我現在就試試這個.. – 2013-03-07 14:48:02

+0

絕對是一個更好的方法來讓它執行這個異步和'InvokeOnMainThread'進度框。 – valdetero 2013-03-07 16:24:15