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