C# 通过WebClient/BeginInvoke方法创建多线程Web下载

C# 通过WebClient/BeginInvoke方法创建多线程Web下载,c#,wpf,multithreading,asynchronous,C#,Wpf,Multithreading,Asynchronous,我实际上有以下代码: private Stopwatch _sw; public void DownloadFile(string url, string fileName) { string path = @"C:\DL\"; Thread bgThread = new Thread(() => { _sw = new Stopwatch(); _sw.Start(); labelDownloadAudioSt

我实际上有以下代码:

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会变成液体。所以我搜索了一下,发现了这个:


答案是将所有内容打包到一个单独的线程中,该线程执行与
DownloadFileAsync
的交互,但我遇到了一个错误,即找不到
BeginInvoke
方法

调用方法和BeginInvoke方法在System.Windows.Forms.Control类上实现。如果您不是在表单类中编写代码,则不能使用此方法。若要解决此问题,请从System.Windows.Forms.Control类继承作业类,然后可以使用BeginInvoke方法。请注意,您必须在主线程上创建实例

public class JobClass : System.Windows.Forms.Control {
.....
}

使用WPF时,
BeginInvoke
方法不会被
窗口
类公开,就像WinForms中的
表单
一样。相反,您应该使用
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;
    });
}

你想在你的
窗体中调用
this.BeginInvoke
吗?是的,但是我如何在WPF项目中使用它?我如何在WPF项目中使用它?