9

WebClient のDownloadProgressChangedイベントにイベント ハンドラを追加しましたが、起動しないようです。ファイルは正常にダウンロードされますが、進行状況は更新されません。

public class DownloadFile
{
    private File file = null;

    public DownloadFile(File file)
    {
        this.file = file;
    }

    public void startDownloadThread()
    {
        Console.WriteLine("Starting Download : "+file.URL);

        var t = new Thread(() => DownloadThread(file));
        t.Start();
    }

    public Action<string> action_error_downloadFailed = Console.WriteLine;
    private void DownloadThread(File file) //Unnecessary argument but whatever ;D
    {
        try
        {
            string url = file.URL;
            string savepath = file.DestinationDir + "\\" + file.Filename;

            WebClient_B client = new WebClient_B();
            client.Proxy = null; //default to no proxy
            client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
            client.DownloadFile(url, savepath);

            Console.WriteLine("Download finished :" + file.Filename);
        }
        catch (Exception ex)
        {
            if (action_error_downloadFailed != null)
                action_error_downloadFailed("Download failed :"+ex.Message);
        }
    }

    private void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
    {
        try
        {
            if (file.TotalSize == 0)
                file.TotalSize = (int)e.TotalBytesToReceive;
            file.CurrentSize = (int)e.BytesReceived;

            Form_DownloadManager.rebuildQueue();

            Console.WriteLine("{0}    downloaded {1} of {2} bytes. {3} % complete...",
            (string)e.UserState,
            e.BytesReceived,
            e.TotalBytesToReceive,
            e.ProgressPercentage);
        }
        catch (Exception ex) { Console.WriteLine("client_DownloadProgressChanged error : "+ex.Message); }
    }
}

出力:

Starting Download : http://x.x.x/y/z.zip
'projectname.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Configuration\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Configuration.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
The thread '<No Name>' (0x3b8c) has exited with code 0 (0x0).
Download finished :z.zip

サーバーがダウンロード要求を拒否し続けたためWebClient_B、クラスに useragent+cookiecontainer 機能を追加する必要があったため、使用しています。WebClientただし、イベントは「標準」WebClientクラスでも発生しませんでした。だから、それは問題ではないはずです。とにかく; クラスへのリンク

4

2 に答える 2

14
client.DownloadFile(url, savepath);

ファイルをダウンロードするには、非同期バージョンを使用する必要があります。現在、ブロッキング同期バージョンを使用しています。

msdnドキュメントからWebClient.DownloadProgressChanged

非同期ダウンロード操作がデータの一部またはすべてを正常に転送したときに発生します。

あなたの場合、それは次のようになります。

client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
client.DownloadFileAsync (url, savepath);

メソッドは直接結果を返さないため、このリファクタリングは問題になりません。ただし、メソッドが呼び出し元に戻るまでにダウンロードが完了していない可能性が高いことに注意してください。

于 2012-06-13T13:00:38.177 に答える
11

進行状況の更新を取得しながら WebClient を同期的に使用する場合は、ここで説明するこの方法を利用できます。

http://alexfeinberg.wordpress.com/2014/09/14/how-to-use-net-webclient-synchronously-and-still-receive-progress-updates/

public void DownloadFile(Uri uri, string destination)
{
  using (var wc = new WebClient())
  {
    wc.DownloadProgressChanged += HandleDownloadProgress;
    wc.DownloadFileCompleted += HandleDownloadComplete;

    var syncObject = new object();
    lock (syncObject)
    {
       wc.DownloadFileAsync(uri, destination, syncObject);
       // This would block the thread until download completes
       Monitor.Wait(syncObject);
    }
  }
 
  // Do more stuff after download was complete
}

private void HandleDownloadComplete(object sender, AsyncCompletedEventArgs args)
{
   lock (args.UserState)
   {  
      // releases blocked thread
      Monitor.Pulse(args.UserState);
   }
}


private void HandleDownloadProgress(object sender, DownloadProgressChangedEventArgs args)
{
  // Process progress updates here
}
于 2014-09-14T15:12:56.087 に答える