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

進行状況が発生したとき、またはダウンロードが終了したときに呼び出される2つのメソッド引数を追加しました。

このメソッドを呼び出すには、次を使用します。

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 に答える