每次下载一个文件
本文关键字:一个 文件 下载 | 更新日期: 2023-09-27 18:03:53
我有foreach,它解析出文件URL。在每个循环结束时,我想下载文件,但是,就像我现在拥有的那样,它下载了所有文件。我需要弄清楚如何阻止UI线程(其中有foreach),而下载完成。
我现在的情况:
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();
});
}
所以,有没有办法等待UI线程,而下载文件同步完成,然后继续我的大foreach?
你可以这样做:
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);