2013-03-14 1 views
-1

J'ai foreach, qui analyse l'URL du fichier. À la fin de chaque cycle, je veux télécharger le fichier, mais, comme je l'ai maintenant, il les télécharge tous. J'ai besoin de comprendre comment bloquer le thread UI (qui a foreach dedans) pendant que le téléchargement se termine.Télécharger les fichiers un à la fois

Ce que j'ai maintenant:

foreach (... in ...) 
{ 
    //some code that extracts FileURL and fileName 
    downloadFile(FileURL, fileName) 
    //should wait here, without blocking UI 
    //are.WaitOne(); //this blocks the UI 
} 

AutoResetEvent are = new AutoResetEvent(false); 
void downloadFile(String FileURL, String fileName) 
{ 
    Thread bgThread = new Thread(() => 
    { 
    WebClient FileClient = new WebClient(); 
    FileClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(FileClient_DownloadProgressChanged); 
    FileClient.DownloadFileCompleted += new AsyncCompletedEventHandler(FileClient_DownloadFileCompleted); 
    FileClient.DownloadFileAsync(new Uri(FileURL), fileName); 
    //should wait here, without blocking UI 
    //are.WaitOne(); //this either downloads one, or both in paralel. 
    }); 
    bgThread.Start(); 

} 

void FileClient_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) 
{ 
    this.BeginInvoke((MethodInvoker)delegate 
    { 
    label5.Text = String.Format("Downloaded {0} of {1} bytes...", e.BytesReceived.ToString(), e.TotalBytesToReceive.ToString()); 
    progressBar1.Value = e.ProgressPercentage; 
    }); 
} 

void FileClient_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e) 
{ 
    this.BeginInvoke((MethodInvoker)delegate 
    { 
    label5.Text = "Done."; 
    //stop the waiting 
    are.Set(); 
    }); 
} 

Alors, est-il un moyen d'attendre thrad de l'interface utilisateur tout en DownloadFileAsync se termine, puis continuer avec mon grand foreach?

Répondre

0

Vous pouvez faire quelque chose comme ceci:

List<Task> tasks = new List<Task>(); 
foreach(....) 
{ 

Thread bgThread = new Thread(() => 
    { 
    WebClient FileClient = new WebClient(); 
    FileClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(FileClient_DownloadProgressChanged); 
    FileClient.DownloadFileCompleted += new AsyncCompletedEventHandler(FileClient_DownloadFileCompleted); 
    FileClient.DownloadFileAsync(new Uri(FileURL), fileName); 
    //should wait here, without blocking UI 
    //are.WaitOne(); //this either downloads one, or both in paralel. 
    }); 
    bgThread.Start(); 

    tasks.Add(bgThread); 


} 

var arr = tasks.ToArray(); 
Task.WaitAll(arr); 
+0

Si je comprends bien, ils seraient encore courir tout en même temps. Ce projet pourrait avoir hundread ou des fichiers dans foreach. Une telle situation apporterait des temps de fin aux ressources du système. C'est pourquoi je voudrais avoir un moyen de télécharger les fichiers un à la fois. – hithfaeron

+0

donc, après bgThread.Start(); appelez bgThread.Wait(); –

+0

Non, cela ne fonctionne pas. Thread.Join() ne fonctionne pas non plus et la recherche de bgThread.IsAlive ne fonctionne pas non plus. – hithfaeron

Questions connexes