2012-03-01 28 views
0

我知道進度條本身已經被要求死亡,但我遇到了麻煩。我需要通過FTP下載文件,我使用WebClient,下載的數據必須保存到字節數組中,但WebClient.DownloadDataAsync不能直接返回,所以我必須使用DownloadDataCompleted方法來訪問數據。一切都沒問題,但問題是我不能「暫停」IEnumerator塊而沒有阻塞整個線程,如果我不暫停它,應用程序崩潰,因爲它的字節數組不存在試圖訪問它。當要下載的文件在http中時,我使用了WWW並沒有任何問題,但必須將其移至FTP。使用WebClient.DownloadData的作品,但我被要求包括一個進度條。總之,here's代碼:我可以在迭代器塊內創建下載進度條嗎?

IEnumerator DownloadGame(Dictionary<string, string> settingsDict) 
    { 
     statusText = "Starting download..."; 
     WebClient request = new WebClient(); 
     request.Credentials = new NetworkCredential("user", "password"); 
     request.DownloadDataCompleted += DownloadDataCompleted; 

     //byte[] fileData = request.DownloadData(settingsDict["downloadlink"]); This works, but is no good since it blocks the thread 
    request.DownloadDataAsync(new Uri(settingsDict["downloadlink"]),"somefilepath"); 


    //do{}while(!downloadFinished); This also works but blocks the thread anyway 


    //Process the update 
    string tmpRoot = TMPFolder(); 
    string tmpFolder = tmpRoot + Application.platform + settingsDict["latestVersion"] + "/"; 
    if (!UnzipUpdate(fileData, tmpFolder))//fail here, in this case fileData is global 
    { 
     DeleteDirectory(tmpRoot); 
     yield break; 
    } 
    if (!ProcessUpdateData(tmpFolder)) 
    { 
     DeleteDirectory(tmpRoot); 
     yield break; 
    } 
    DeleteDirectory(tmpRoot); 

    settingsDict["thisVersion"] = GetNextVersion(); 
} 

void DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e){ 

    fileData = e.Result; 
    downloadFinished = true; 
} 

回答

0

你可以使用像這樣基於以前Stakoverflow後..

最簡單的方法是使用BackgroundWorker,把你的代碼放到DoWork事件處理程序。並用BackgroundWorker.ReportProgress報告進度。

的基本思想:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{ 
    var ftpWebRequest = (FtpWebRequest)WebRequest.Create("ftp://xxx.com"); 
    ftpWebRequest.Method = WebRequestMethods.Ftp.UploadFile; //or DownLoad 
    using (var inputStream = File.OpenRead(fileName)) 
    using (var outputStream = ftpWebRequest.GetRequestStream()) 
    { 
     var buffer = new byte[1024 * 1024]; 
     int totalReadBytesCount = 0; 
     int readBytesCount; 
     while ((readBytesCount = inputStream.Read(buffer, 0, buffer.Length)) > 0) 
     { 
      outputStream.Write(buffer, 0, readBytesCount); 
      totalReadBytesCount += readBytesCount; 
      var progress = totalReadBytesCount * 100.0/inputStream.Length; 
      backgroundWorker1.ReportProgress((int)progress); 
     } 
    } 
} 

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) 
{ 
    progressBar.Value = e.ProgressPercentage; 
} 

確保WorkerReportsProgress啓用

backgroundWorker2.WorkerReportsProgress = true; 

隨着BackgroundWorker你也可以輕鬆實現上傳取消。

+0

線程確實有幫助,謝謝。 – Samssonart 2012-03-05 16:47:49

+0

不客氣..快樂的編碼Marco – MethodMan 2012-03-05 16:53:32