从另一个类返回client_DownloadProgressChanged事件

问题描述:

我试图用一个下载程序创建一个类,以便我可以继续重用,以便在一段时间后我不会获得巨大的代码。但我似乎无法返回client_DownloadProgressChanged事件。这是我现在的代码:从另一个类返回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; 
     } 
    } 
+0

你也可以在其他类中写**事件处理程序**。 – adatapost 2012-08-06 12:34:35

+0

我真的不知道我该怎么做。有小费吗? – 2012-08-06 12:35:40

首先,您的Thread是多余的。如果你读msdn articleDownloadFileAsync您将看到:

This method does not block the calling thread.

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

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

一个问题,如果我可以:那些论点到底是什么,我如何填写它们?我也得到这个错误:'错误不能隐式转换类型'System.Action '到'System.Net.DownloadProgressChangedEventHandler'' – 2012-08-06 13:10:16

+0

对不起,错误修正了。调用请参阅编辑。 – Rafal 2012-08-06 13:27:18

+0

感谢:D!通过他们的方式,我下载文件时似乎无法获得正确的百分比。 – 2012-08-06 17:24:25

我想,最简单的方法是改变你的静态方法与实例方法(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); 
     } 
    } 

}