我实际上有以下代码:
private Stopwatch _sw;
public void DownloadFile(string url, string fileName)
{
string path = @"C:\DL\";
Thread bgThread = new Thread(() =>
{
_sw = new Stopwatch();
_sw.Start();
labelDownloadAudioStatusText.Visibility = Visibility.Visible;
using (WebClient webClient = new WebClient())
{
webClient.DownloadFileCompleted +=
new AsyncCompletedEventHandler(DownloadCompleted);
webClient.DownloadProgressChanged +=
new DownloadProgressChangedEventHandler(DownloadStatusChanged);
webClient.DownloadFileAsync(new Uri(url), path + fileName);
}
});
bgThread.Start();
}
void DownloadStatusChanged(object sender, DownloadProgressChangedEventArgs e)
{
this.BeginInvoke((MethodInvoker) delegate
{
int percent = 0;
if (e.ProgressPercentage != percent)
{
percent = e.ProgressPercentage;
progressBarDownloadAudio.Value = percent;
labelDownloadAudioProgress.Content = percent + "%";
labelDownloadAudioDlRate.Content =
(Convert.ToDouble(e.BytesReceived)/1024/
_sw.Elapsed.TotalSeconds).ToString("0.00") + " kb/s";
Thread.Sleep(50);
}
});
}
private void DownloadCompleted(object sender, AsyncCompletedEventArgs e)
{
this.BeginInvoke((MethodInvoker) delegate
{
labelDownloadAudioDlRate.Content = "0 kb/s";
labelDownloadAudioStatusText.Visibility = Visibility.Hidden;
});
}
我的问题是,在没有外部线程的先前版本中,整个GUI偶尔冻结,并且在下载完成时GUI是流动的。所以我用Google搜索并找到了这个:https://stackoverflow.com/a/9459441/2288470
答案是将所有内容打包到一个单独的线程中,该线程执行与DownloadFileAsync
的交互,但我得到了错误,找不到BeginInvoke
方法。
答案 0 :(得分:1)
使用WPF时,BeginInvoke
类不会公开Window
方法,就像WinForms中的Form
一样。相反,您应该使用Dispatcher.BeginInvoke
。
工作代码:
private Stopwatch _sw;
public void DownloadFile(string url, string fileName)
{
string path = @"C:\DL\";
Thread bgThread = new Thread(() =>
{
_sw = new Stopwatch();
_sw.Start();
labelDownloadAudioStatusText.Visibility = Visibility.Visible;
using (WebClient webClient = new WebClient())
{
webClient.DownloadFileCompleted +=
new AsyncCompletedEventHandler(DownloadCompleted);
webClient.DownloadProgressChanged +=
new DownloadProgressChangedEventHandler(DownloadStatusChanged);
webClient.DownloadFileAsync(new Uri(url), path + fileName);
}
});
bgThread.Start();
}
void DownloadStatusChanged(object sender, DownloadProgressChangedEventArgs e)
{
Dispatcher.BeginInvoke((MethodInvoker) delegate
{
int percent = 0;
if (e.ProgressPercentage != percent)
{
percent = e.ProgressPercentage;
progressBarDownloadAudio.Value = percent;
labelDownloadAudioProgress.Content = percent + "%";
labelDownloadAudioDlRate.Content =
(Convert.ToDouble(e.BytesReceived)/1024/
_sw.Elapsed.TotalSeconds).ToString("0.00") + " kb/s";
Thread.Sleep(50);
}
});
}
private void DownloadCompleted(object sender, AsyncCompletedEventArgs e)
{
Dispatcher.BeginInvoke((MethodInvoker) delegate
{
labelDownloadAudioDlRate.Content = "0 kb/s";
labelDownloadAudioStatusText.Visibility = Visibility.Hidden;
});
}
答案 1 :(得分:0)
Invoke方法和BeginInvoke方法在System.Windows.Forms.Control类上实现。如果您没有在Form Class中编写代码,则无法使用此方法。若要解决此问题,从System.Windows.Forms.Control类继承您的Job类,然后您可以使用BeginInvoke方法。请注意,您必须在主线程上创建实例。
public class JobClass : System.Windows.Forms.Control {
.....
}