I added an event handler to the WebClient's DownloadProgressChanged
event, but it never seems to fire. The file successfully downloads, but without having its progress updated.
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); }
}
}
Output:
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
I am using WebClient_B
because I had to add useragent+cookiecontainer functionality to the WebClient
class since my server kept rejecting the download request. The event never fired with the 'standard' WebClient
class either, though. So that shouldn't be the problem. But anyway; link to class
client.DownloadFile(url, savepath);
You have to use the async version to download a file, currently you use the blocking, synchronous version.
From the msdn docs for WebClient.DownloadProgressChanged
:
Occurs when an asynchronous download operation successfully transfers some or all of the data.
In your case that would be:
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
client.DownloadFileAsync (url, savepath);
Since your method does not directly return any result, this refactoring shouldn't be a problem, note though that the download most likely has not been completed by the time the method returns to the caller.
If you want to use WebClient synchronously, while getting progress updates, you can rely on this method detailed here:
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
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With