简体   繁体   English

下载文件时如何显示进度栏?

[英]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;
}

Notes: 笔记:

  1. You can create the FormClosing method by double clicking the FormClosing event in your window's property box. 您可以通过在窗口的属性框中双击FormClosing事件来创建FormClosing方法。
  2. Calling 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM