C# 我可以在迭代器块中创建下载进度条吗?

C# 我可以在迭代器块中创建下载进度条吗?,c#,ftp,webclient-download,C#,Ftp,Webclient Download,我知道进度条已经被要求去死了,但我在其中遇到了麻烦。我需要通过FTP下载文件,我正在使用WebClient,下载的数据必须保存到字节数组中,但是WebClient.DownloadDataAsync不能直接返回它,所以我必须使用DownloadDataCompleted方法来访问数据。到目前为止一切正常,但问题是我不能暂停IEnumerator块而不阻止整个线程,如果我不暂停它,应用程序就会崩溃,因为当它尝试访问它时字节数组不存在。当要下载的文件是http时,我使用了WWW,没有问题,但它必须移

我知道进度条已经被要求去死了,但我在其中遇到了麻烦。我需要通过FTP下载文件,我正在使用WebClient,下载的数据必须保存到字节数组中,但是WebClient.DownloadDataAsync不能直接返回它,所以我必须使用DownloadDataCompleted方法来访问数据。到目前为止一切正常,但问题是我不能暂停IEnumerator块而不阻止整个线程,如果我不暂停它,应用程序就会崩溃,因为当它尝试访问它时字节数组不存在。当要下载的文件是http时,我使用了WWW,没有问题,但它必须移动到FTP。使用WebClient.DownloadData是可行的,但我被要求包含一个进度条。无论如何,下面是代码:

    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;
 }

您可以根据以前的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,您还可以轻松实现上传取消