从另一个类返回client_DownloadProgressChanged事件

时间:2012-08-06 12:31:30

标签: c#

我正在尝试使用我可以继续重复使用的下载程序创建一个类,所以一段时间后我就不会得到一个巨大的代码。但我似乎无法返回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;
        }
    }

2 个答案:

答案 0 :(得分:1)

首先,您的Thread是多余的。如果您阅读有关DownloadFileAsync的{​​{3}},您会看到:

  

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

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

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 */});

答案 1 :(得分: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);
        }
    }

}