【发布时间】:2016-10-12 14:17:25
【问题描述】:
这是我用来下载文件然后计算剩余时间和 kbps 的一些代码。然后它将通过更新文本框将这些结果发布到表单上,并且它有一个进度条。我遇到的问题是 UI 冻结,我想这可能是我使用秒表的方式,但不确定。有人有意见吗?
/// Downloads the file.
private void Download_Begin()
{
web_client = new System.Net.WebClient();
web_client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(Download_Progress);
web_client.DownloadFileCompleted += new AsyncCompletedEventHandler(Download_Complete);
stop_watch = new System.Diagnostics.Stopwatch();
stop_watch.Start();
try
{
if (Program.Current_Download == "Install_Client.exe")
{
web_client.DownloadFileAsync(new Uri("http://www.website.com/Client/Install_Client.exe"), @"C:\Downloads\Install_Client.exe");
}
else
{
web_client.DownloadFileAsync(new Uri((string.Format("http://www.website.com/{0}", Program.Current_Download))), (string.Format(@"C:\Downloads\{0}", Program.Current_Download)));
}
}
catch(Exception)
{
stop_watch.Stop();
}
Program.Downloading = true;
Download_Success = false;
}
/// -------------------
/// Tracks download progress.
private void Download_Progress(object sender, DownloadProgressChangedEventArgs e)
{
double bs = e.BytesReceived / stop_watch.Elapsed.TotalSeconds;
this.label_rate.Text = string.Format("{0} kb/s", (bs / 1024d).ToString("0.00"));
long bytes_remaining = e.TotalBytesToReceive - e.BytesReceived;
double time_remaining_in_seconds = bytes_remaining / bs;
var remaining_time = TimeSpan.FromSeconds(time_remaining_in_seconds);
string hours = remaining_time.Hours.ToString("00");
if (remaining_time.Hours > 99)
{
hours = remaining_time.Hours.ToString("000");
}
this.time_remaining.Text = string.Format("{0}::{1}::{2} Remaining", hours, remaining_time.Minutes.ToString("00"), remaining_time.Seconds.ToString("00"));
progressBar1.Maximum = (int)e.TotalBytesToReceive / 100;
progressBar1.Value = (int)e.BytesReceived / 100;
if (e.ProgressPercentage == 100)
{
Download_Success = true;
}
}
/// -------------------------
【问题讨论】:
-
我没有看到任何会导致冻结的代码。在您的程序上使用分析器,几乎每个程序都有过滤 UI 冻结代码的功能。
-
@ScottChamberlain 好的,看起来文件的实际下载,异步下载的 CPU 使用率非常高。不知道为什么会这样做。
-
大卫,请参考上一个问题。 stackoverflow.com/questions/27261797/… 下载进度的回调似乎经常被调用。而且由于您在该回调中进行了一些 UI 更新,因此可能会导致您的 UI 冻结。建议的答案似乎也适用于您的情况。
标签: c# multithreading winforms user-interface thread-safety