0

我正在尝试使用可以继续重用的下载器创建一个类,这样我就不会在一段时间后获得大量代码。但我似乎无法返回该client_DownloadProgressChanged事件。这是我现在拥有的代码:

public static string progress;
    public static int percent;
    static WebClient client = new WebClient();
    /// <summary>
    /// Download a file from the internet
    /// </summary>
    /// <param name="url">The URL to download from</param>
    /// <param name="path">The path to save to don't forget the / at the end</param>
    /// <param name="filename">The filename of the file that is going to be download</param>
    public static string DownloadFile(string url, string path, string filename)
    {
        try
        {
            Thread bgThread = new Thread(() =>
                                             {
                                                 client.DownloadProgressChanged += client_DownloadProgressChanged;
                                                 client.DownloadFileCompleted += client_DownloadFileCompleted;
                                                 client.DownloadFileAsync(new Uri(url), path + filename);
                                             });
            bgThread.Start();
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        };
        return progress;
    }

    static void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
    {
        double bytesIn = double.Parse(e.BytesReceived.ToString(CultureInfo.InvariantCulture));
        double totalBytes = double.Parse(e.TotalBytesToReceive.ToString(CultureInfo.InvariantCulture));
        double percentage = bytesIn/totalBytes*100;
        progress = "Downloaded " + e.BytesReceived + " of " + e.TotalBytesToReceive;
        percent = int.Parse(Math.Truncate(percentage).ToString(CultureInfo.InvariantCulture));
        while (client.IsBusy)
        {
            return progress;
        }
    }
4

2 回答 2

1

首先,你Thread是多余的。如果您阅读有关您将看到的msdn 文章:DownloadFileAsync

此方法不会阻塞调用线程。

考虑到这一点,您的方法会变得更简单:

public static string DownloadFile(string url, string path, string filename, Action<string,double> progressNotification,Action finishNotification)
{
     DownloadProgressChangedEventHandler progressReaction  = (s,e)=>
              {                               
                      var progress = "Downloaded " + e.BytesReceived + " of " + e.TotalBytesToReceive;
                      var percent = Math.Truncate(e.BytesReceived / (double)e.TotalBytesToReceive * 100);

                      while (client.IsBusy)
                      {
                         progressNotification(progress, percent);
                      }                          
              };
     WebClient client = new WebClient();
     client.DownloadProgressChanged += progressReaction;
     client.DownloadFileCompleted += (s,e) => finishNotification();
     client.DownloadFileAsync(new Uri(url), path + filename);
}                           

我添加了两个方法参数,它们将在取得进展或下载完成时调用。

要调用此方法,请使用:

DownloadFile(url,path,fileName,
 (message,precentage)=>{ /* do some progress bar update or something */ },
 ()=>{ /* hide progressbar or some logic after finish */});
于 2012-08-06T12:59:26.113 回答
0

我想最简单的方法是将您的静态方法更改为实例方法(client_DownloadProgressChanged 将是一个私有方法)并创建一个自定义事件,因此无论何时使用它,只需订阅该事件,就像 DownloadProgressChanged 事件本身一样。

public class Downloader
{
    public delegate void DownloadProgressHandler(object sender, string progress);
    public event DownloadProgressHandler DownloadProgressChanged;

    public static string progress;
    public static int percent;
    static WebClient client = new WebClient();
    /// <summary>
    /// Download a file from the internet
    /// </summary>
    /// <param name="url">The URL to download from</param>
    /// <param name="path">The path to save to don't forget the / at the end</param>
    /// <param name="filename">The filename of the file that is going to be download</param>
    public string DownloadFile(string url, string path, string filename)
    {
        try
        {
            Thread bgThread = new Thread(() =>
            {
                client.DownloadProgressChanged += client_DownloadProgressChanged;
                client.DownloadFileAsync(new Uri(url), path + filename);
            });
            bgThread.Start();
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        };
        return progress;
    }

    private void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
    {
        double bytesIn = double.Parse(e.BytesReceived.ToString(CultureInfo.InvariantCulture));
        double totalBytes = double.Parse(e.TotalBytesToReceive.ToString(CultureInfo.InvariantCulture));
        double percentage = bytesIn / totalBytes * 100;
        progress = "Downloaded " + e.BytesReceived + " of " + e.TotalBytesToReceive;
        percent = int.Parse(Math.Truncate(percentage).ToString(CultureInfo.InvariantCulture));
        while (client.IsBusy)
        {
            if (DownloadProgressChanged != null)
                DownloadProgressChanged(this, progress);
        }
    }

}
于 2012-08-06T13:00:54.547 回答