【发布时间】:2012-04-04 18:43:09
【问题描述】:
我正在尝试编写一个 C# Windows 应用程序来下载文件(等待下载完成 - 提供一些进度指示器),然后执行下载的文件。我想我要么需要:
- 具有进度指示器且不会使我的应用程序无响应的同步下载
- 等待下载完成然后尝试执行的异步下载。
前者(同步下载)似乎可以满足我的要求,但我找不到任何方式来指示进度,而且它似乎使我的程序无响应(就像它挂起一样)——这可能会导致用户关闭应用程序,而不是等待它完成下载。
后来(异步下载)我已经能够使用进度指示器等来完成,但发生的是下载开始并且我的应用程序在完成下载之前立即尝试安装它,这当然会失败。
那么实现这一点的最佳方法是什么?下面是我目前使用进度条进行异步下载的代码。
2012 年 4 月 10 日编辑
旧代码处理起来很麻烦,所以这就是我目前拥有的。它可以工作,只是它不更新进度条。
private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
List<App> FilesToDownload = e.Argument as List<App>;
foreach (App Program in FilesToDownload) // Loop through List with foreach
{
//string Text = ;
UpdateRichTextBox("Downloading " + Program.Filename + "... Please wait");
string Source = Program.DownloadLocation + "/" + Program.Filename;
string Destination = System.AppDomain.CurrentDomain.BaseDirectory + Program.Filename;
WebClient webClient = new WebClient();
webClient.DownloadFile(Source, @Destination);
}
UpdateRichTextBox("File download complete");
foreach (App Program in FilesToDownload) // Loop through List with foreach
{
string Filename = Program.Filename;
string Arguments = Program.InstallParameters;
if (Filename != "advisorinstaller.exe")
{
Process p = new Process();
p.StartInfo.FileName = System.AppDomain.CurrentDomain.BaseDirectory + Filename;
p.StartInfo.Arguments = Arguments;
p.Start();
p.WaitForExit();
}
else
{
MessageBox.Show("About to install Belarc Advisor. This may take 10-15 minutes to run - do not shutdown this program. Click OK when ready to proceed.");
}
}
}
private void backgroundWorker1_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
private void backgroundWorker1_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
UpdateRichTextBox("Install Complete");
}
2012 年 4 月 11 日编辑
所以我编辑了我的后台工作人员的工作如下:
private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
List<App> FilesToDownload = e.Argument as List<App>;
int counter = 0;
int percent = 0;
foreach (App Program in FilesToDownload) // Loop through List with foreach
{
percent = ((counter / FilesToDownload.Count) * 100);
backgroundWorker1.ReportProgress(percent, "");
UpdateRichTextBox("Downloading " + Program.Filename + "... Please wait");
string Source = Program.DownloadLocation + "/" + Program.Filename;
string Destination = System.AppDomain.CurrentDomain.BaseDirectory + Program.Filename;
WebClient webClient = new WebClient();
webClient.DownloadFile(Source, @Destination);
counter++;
}
//backgroundWorker1.ReportProgress(100, "Complete!");
}
如果我取消最后一行的注释,进度条会变为 100%。但它没有使用:
percent = ((counter / FilesToDownload.Count) * 100);
backgroundWorker1.ReportProgress(percent, "");
有什么想法吗?
【问题讨论】:
-
执行的代码在哪里?会认为这将在 client_DownloadFileCompleted 处理程序中处理。
-
用户按下一个按钮来检查某些复选框是否被选中,然后调用方法进行安装。安装方法依次调用下载文件方法,然后尝试安装下载的文件。我看看能不能发个例子。
-
嗯,那你为什么要在 Completed 处理程序之外做 Process 的东西呢?似乎那将是完成工作或启动另一个线程来完成工作的地方。您之前提到过尝试在下载失败之前执行(当然),那么为什么不直接将该执行放入指示下载完成的方法中呢?
标签: c# asynchronous download