[英]How do I show Progress Bar when Downloading a File?
I'm brand new to coding with c# so can someone tell me how I can include code into this to show the progress bar of file downloading? 我是使用c#进行编码的新手,所以有人可以告诉我如何在其中包含代码以显示文件下载的进度条吗?
private void button4_Click(object sender, EventArgs e)
{
using (var client = new WebClient())
{
MessageBox.Show("File will start downloading");
var path = System.IO.Path.Combine(System.IO.Path.GetTempPath(), "SOMEFILENAME.exe");
client.DownloadFile("GOOGLE DRIVE LINK", path);
MessageBox.Show("File has been downloaded!");
System.Diagnostics.Process.Start(path);
}
}
To update a progress bar while your WebClient
downloads data you have to use a function that does this task in the background . 要在
WebClient
下载数据时更新进度条,您必须使用在后台执行此任务的功能。 WebClient
has a useful function called DownloadFileAsync
. WebClient
具有一个有用的功能,称为DownloadFileAsync
。 This function does exactly that: It downloads in the background. 该功能正是这样做的:它在后台下载。
The code so with this change: 更改后的代码如下:
private void button4_Click(object sender, EventArgs e)
{
using (var client = new WebClient())
{
MessageBox.Show("File will start downloading");
var path = System.IO.Path.Combine(System.IO.Path.GetTempPath(), "SOMEFILENAME.exe");
client.DownloadFileAsync(new Uri("GOOGLE DRIVE LINK"), path);
MessageBox.Show("File has been downloaded!");
System.Diagnostics.Process.Start(path);
}
}
Unfortunately we have a problem now. 不幸的是,我们现在有一个问题。 The method starts the download in the background and your code immediately continues.
该方法在后台开始下载,您的代码立即继续。 This means you press your button, the first MessageBox pops up, the second MessageBox pops up right after the first one and if your download isn't completed when you close the second one your file is executed too early.
这意味着您按下按钮,第一个MessageBox弹出,第二个MessageBox紧接在第一个之后弹出,如果在关闭第二个MessageBox时下载未完成,则文件执行得太早了。
To avoid this WebClient
has events . 为避免此
WebClient
发生事件 。 The one we need is called DownloadFileCompleted
. 我们需要的一个称为
DownloadFileCompleted
。 As the name suggests it executes whatever you want when the download is completed. 顾名思义,下载完成后,它将执行您想要的任何操作。 So let's look at the new code:
因此,让我们看一下新代码:
string path = System.IO.Path.Combine(System.IO.Path.GetTempPath(), "SOMEFILENAME.exe"); // We need our path to be global
private void button4_Click(object sender, EventArgs e)
{
using (var client = new WebClient())
{
client.DownloadFileCompleted += client_DownloadFileCompleted; // Add our new event handler
MessageBox.Show("File will start downloading");
client.DownloadFileAsync(new Uri("GOOGLE DRIVE LINK"), path);
}
}
private void client_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e) // This is our new method!
{
MessageBox.Show("File has been downloaded!");
System.Diagnostics.Process.Start(path);
}
Our next problem: client
is inside a using block. 我们的下一个问题:
client
位于using块内。 This is great for foreground downloads but if we do it asynchronously (that's what doing it in the background is called) your client
will be dead as soon as the block is left which is immediately after the download has been started . 这对于前台下载非常有用,但是如果我们异步执行(这就是在后台执行的操作),则在下载开始后立即离开该块,您的
client
就会死掉。 So let's make our client
global to be able to destroy it later on. 因此,让我们使
client
全球性client
,以便以后可以销毁它。
string path = System.IO.Path.Combine(System.IO.Path.GetTempPath(), "SOMEFILENAME.exe");
WebClient client; // Here it is!
private void button4_Click(object sender, EventArgs e)
{
client = new WebClient(); // Create a new client here
client.DownloadFileCompleted += client_DownloadFileCompleted; // Add our new event handler
MessageBox.Show("File will start downloading");
client.DownloadFileAsync(new Uri("GOOGLE DRIVE LINK"), path);
}
private void client_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e) // This is our new method!
{
MessageBox.Show("File has been downloaded!");
System.Diagnostics.Process.Start(path);
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (client != null)
client.Dispose(); // We have to delete our client manually when we close the window or whenever you want
}
Now let's assume the user can press the button a second time before the download is completed. 现在,假设用户可以在下载完成之前再次按下按钮。 Our client would be overwritten then and the download would be canceled.
我们的客户将被覆盖,然后下载将被取消。 So let's just ignore the button press if we're already downloading something and only create the new client if we don't have one.
因此,如果我们已经下载了某些内容,就不要理会按钮的按下,而如果我们没有下载新的客户端,那就只创建它。 New code:
新代码:
string path = System.IO.Path.Combine(System.IO.Path.GetTempPath(), "SOMEFILENAME.exe");
WebClient client;
private void button4_Click(object sender, EventArgs e)
{
if (client != null && client.IsBusy) // If the client is already downloading something we don't start a new download
return;
if (client == null) // We only create a new client if we don't already have one
{
client = new WebClient(); // Create a new client here
client.DownloadFileCompleted += client_DownloadFileCompleted; // Add our new event handler
}
MessageBox.Show("File will start downloading");
client.DownloadFileAsync(new Uri("GOOGLE DRIVE LINK"), path);
}
private void client_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e) // This is our new method!
{
MessageBox.Show("File has been downloaded!");
System.Diagnostics.Process.Start(path);
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (client != null)
client.Dispose(); // We have to delete our client manually when we close the window or whenever you want
}
Now that the boring part is done let's come to your problem: Viewing the progress in a progress bar. 现在完成了无聊的部分,让我们来解决您的问题:在进度栏中查看进度。
WebClient
has got another event called DownloadProgressChanged
. WebClient
还有另一个名为DownloadProgressChanged
事件。 We can use it to update our progress bar. 我们可以用它来更新进度条。
Talking about progress bars: In Windows Forms you can create one by searching for ProgressBar
in the tool bow window in Visual Studio. 讨论进度条:在Windows窗体中,可以通过在Visual Studio的工具弓窗口中搜索
ProgressBar
来创建一个。 Then place it somewhere in your window. 然后将其放在窗口中的某个位置。 The
ProgressBar
component has a few properties which are important for its range. ProgressBar
组件具有一些对其范围很重要的属性。 We're lucky, the default values are exactly what we need. 很幸运,默认值正是我们所需要的。
Our updated code (assuming your progress bar is called progressBar1
: 我们更新的代码(假设您的进度条称为
progressBar1
:
string path = System.IO.Path.Combine(System.IO.Path.GetTempPath(), "SOMEFILENAME.exe");
WebClient client;
private void button4_Click(object sender, EventArgs e)
{
if (client != null && client.IsBusy) // If the client is already downloading something we don't start a new download
return;
if (client == null) // We only create a new client if we don't already have one
{
client = new WebClient(); // Create a new client here
client.DownloadFileCompleted += client_DownloadFileCompleted;
client.DownloadProgressChanged += client_DownloadProgressChanged; // Add new event handler for updating the progress bar
}
MessageBox.Show("File will start downloading");
client.DownloadFileAsync(new Uri("GOOGLE DRIVE LINK"), path);
}
private void client_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e) // This is our new method!
{
MessageBox.Show("File has been downloaded!");
System.Diagnostics.Process.Start(path);
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (client != null)
client.Dispose(); // We have to delete our client manually when we close the window or whenever you want
}
private void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) // NEW
{
progressBar1.Value = e.ProgressPercentage;
}
FormClosing
method by double clicking the FormClosing
event in your window's property box. FormClosing
事件来创建FormClosing
方法。 client.Dispose()
is only necessary when your program doesn't exit after closing the window. client.Dispose()
。 In any other case you could get rid of the FormClosing
stuff completely. FormClosing
内容。 That's all finally. 到此为止。 I hope this wasn't too long for you and I could help you.
我希望这对您来说不会太久,我可以为您提供帮助。 Feel free to ask for clarification.
随时要求澄清。 That's what comments are there for.
这就是评论的内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.