Question

Je sais que les barres de progrès en elles-mêmes ont déjà été invitées à mort, mais j'ai des problèmes avec un. J'ai besoin de télécharger un fichier via FTP, j'utilise webClient, les données téléchargées doivent être enregistrées dans un tableau d'octets, mais WebClient.DowloadDataasync ne peut pas les retourner directement, donc je dois utiliser la méthode DownloadDatacompleted pour accéder aux données . Tout jusqu'à ce qu'il soit bon, mais le problème est que je ne peux pas "faire une pause" le bloc d'iEnumerator sans bloquer l'ensemble essaie d'y accéder. Lorsque le fichier à télécharger était en http, j'ai utilisé www et je n'ai eu aucun problème, mais il a dû être déplacé vers FTP. Utilisation de WebClient.DownloadData fonctionne, mais on m'a demandé d'inclure une barre de progression. Quoi qu'il en soit, voici le code:

    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;
 }
Était-ce utile?

La solution

Vous pouvez utiliser quelque chose comme celui-ci en fonction d'un précédent post Stakoverflow.

Le plus facile est d'utiliser BackgroundWorker Et mettez votre code dans DoWork gestionnaire d'événements. Et signaler les progrès avec BackgroundWorker.ReportProgress.

L'idée de base:

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

S'assurer WorkerReportsProgress est autorisé

backgroundWorker2.WorkerReportsProgress = true;

Avec BackgroundWorker Vous pouvez également implémenter une annulation de téléchargement.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top