2012-03-01 29 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