2013-03-07 2 views
0

Пожалуйста, помогите мне со мной нарезать резьбу. Я пытаюсь загрузить файл и в то же время обновить индикатор выполнения BTProgressHUD. Я знаю, что причина, по которой она не работает, связана с загрузкой с использованием основного потока и не позволяет мне обновлять пользовательский интерфейс, но я не могу решить, как правильно использовать пул потоков, чтобы я мог обновить BTProgressHUD, пока файл загружается. Пожалуйста помоги!!Проблема с потоками Monotouch - обновление 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. Я заменил BTProgressHUD на UILabel, но он должен работать так же. Вот он работает:

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

Спасибо за помощь! Я дам вам попробовать сейчас. –

+0

Определенно лучший подход, чтобы заставить это сделать асинхронный и 'InvokeOnMainThread' прогресс. – valdetero

Смежные вопросы