Como: Baixar um arquivo no plano de fundo

Download de um arquivo é uma tarefa comum e muitas vezes é útil executar esta operação potencialmente demorada em uma separada thread.Use o BackgroundWorker componente para realizar essa tarefa com muito pouco código.

Exemplo

O exemplo de código a seguir demonstra como usar um BackgroundWorker componente para carregar um arquivo XML de uma URL. Quando o usuário clica o Fazer o baixar o botãoClick manipulador de eventos chamadas a RunWorkerAsync método de um BackgroundWorker componente para iniciar a operação de baixar. O botão é desabilitado para a duração do baixar do e ativado quando o baixar estiver concluído.A MessageBox Exibe o Sumário do arquivo.

Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Drawing
Imports System.Threading
Imports System.Windows.Forms
Imports System.Xml

Public Class Form1
   Inherits Form
   Private WithEvents backgroundWorker1 As BackgroundWorker
   Private WithEvents dowloadButton As Button
   Private document As XmlDocument = Nothing


   Public Sub New()
      InitializeComponent()
    End Sub

    Private Sub dowloadButton_Click( _
    ByVal sender As Object, _
    ByVal e As EventArgs) _
    Handles dowloadButton.Click

        ' Start the download operation in the background.
        Me.backgroundWorker1.RunWorkerAsync()

        ' Disable the button for the duration of the download.
        Me.dowloadButton.Enabled = False

        ' Wait for the BackgroundWorker to finish the download.
        While Me.backgroundWorker1.IsBusy
            ' Keep UI messages moving, so the form remains 
            ' responsive during the asynchronous operation.
            Application.DoEvents()
        End While

        ' The download is done, so enable the button.
        Me.dowloadButton.Enabled = True
    End Sub

    Private Sub backgroundWorker1_DoWork( _
    ByVal sender As Object, _
    ByVal e As DoWorkEventArgs) _
    Handles backgroundWorker1.DoWork

        document = New XmlDocument()

        ' Replace this file name with a valid file name.
        document.Load("http://www.tailspintoys.com/sample.xml")

        ' Uncomment the following line to
        ' simulate a noticeable latency.
        'Thread.Sleep(5000);
    End Sub

   Private Sub backgroundWorker1_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles backgroundWorker1.RunWorkerCompleted
      If e.Error Is Nothing Then
         MessageBox.Show(document.InnerXml, "Download Complete")
      Else
         MessageBox.Show("Failed to download file", "Download failed", MessageBoxButtons.OK, MessageBoxIcon.Error)
      End If
    End Sub

    ' <summary>
    ' Required designer variable.
    ' </summary>
   Private components As System.ComponentModel.IContainer = Nothing

    ' <summary>
    ' Clean up any resources being used.
    ' </summary>
    ' <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
   Protected Overrides Sub Dispose(disposing As Boolean)
      If disposing AndAlso (components IsNot Nothing) Then
         components.Dispose()
      End If
      MyBase.Dispose(disposing)
    End Sub

   #Region "Windows Form Designer generated code"


    ' <summary>
    ' Required method for Designer support - do not modify
    ' the contents of this method with the code editor.
    ' </summary>
   Private Sub InitializeComponent()
      Me.backgroundWorker1 = New System.ComponentModel.BackgroundWorker()
      Me.dowloadButton = New System.Windows.Forms.Button()
      Me.SuspendLayout()
      ' 
      ' backgroundWorker1
      ' 
      ' 
      ' dowloadButton
      ' 
      Me.dowloadButton.Location = New System.Drawing.Point(12, 12)
      Me.dowloadButton.Name = "dowloadButton"
      Me.dowloadButton.Size = New System.Drawing.Size(75, 23)
      Me.dowloadButton.TabIndex = 0
      Me.dowloadButton.Text = "Download file"
      Me.dowloadButton.UseVisualStyleBackColor = True
      ' 
      ' Form1
      ' 
      Me.AutoScaleDimensions = New System.Drawing.SizeF(6F, 13F)
      Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
      Me.ClientSize = New System.Drawing.Size(104, 54)
      Me.Controls.Add(dowloadButton)
      Me.Name = "Form1"
      Me.Text = "Form1"
      Me.ResumeLayout(False)
    End Sub

   #End Region
End Class


Public Class Program

    ' <summary>
    ' The main entry point for the application.
    ' </summary>
    <STAThread()> _
    Shared Sub Main()
        Application.EnableVisualStyles()
        Application.Run(New Form1())
    End Sub
End Class
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
using System.Xml;

public class Form1 : Form
{
    private BackgroundWorker backgroundWorker1;
    private Button dowloadButton;
    private XmlDocument document = null;

    public Form1()
    {
        InitializeComponent();
    }

    private void dowloadButton_Click(object sender, EventArgs e)
    {
        // Start the download operation in the background.
        this.backgroundWorker1.RunWorkerAsync();

        // Disable the button for the duration of the download.
        this.dowloadButton.Enabled = false;

        // Wait for the BackgroundWorker to finish the download.
        while (this.backgroundWorker1.IsBusy)
        {
            // Keep UI messages moving, so the form remains 
            // responsive during the asynchronous operation.
            Application.DoEvents();
        }

        // The download is done, so enable the button.
        this.dowloadButton.Enabled = true;
    }

    private void backgroundWorker1_DoWork(
        object sender, 
        DoWorkEventArgs e)
    {
        document = new XmlDocument();

        // Replace this file name with a valid file name.
        document.Load(@"http://www.tailspintoys.com/sample.xml");

        // Uncomment the following line to
        // simulate a noticeable latency.
        //Thread.Sleep(5000);
    }

    private void backgroundWorker1_RunWorkerCompleted(
        object sender, 
        RunWorkerCompletedEventArgs e)
    {
        if (e.Error == null)
        {
            MessageBox.Show(document.InnerXml, "Download Complete");
        }
        else
        {
            MessageBox.Show(
                "Failed to download file", 
                "Download failed", 
                MessageBoxButtons.OK, 
                MessageBoxIcon.Error );
        }
    }

    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.IContainer components = null;

    /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }

    #region Windows Form Designer generated code

    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
        this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker();
        this.dowloadButton = new System.Windows.Forms.Button();
        this.SuspendLayout();
        // 
        // backgroundWorker1
        // 
        this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork);
        this.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted);
        // 
        // dowloadButton
        // 
        this.dowloadButton.Location = new System.Drawing.Point(12, 12);
        this.dowloadButton.Name = "dowloadButton";
        this.dowloadButton.Size = new System.Drawing.Size(75, 23);
        this.dowloadButton.TabIndex = 0;
        this.dowloadButton.Text = "Download file";
        this.dowloadButton.UseVisualStyleBackColor = true;
        this.dowloadButton.Click += new System.EventHandler(this.dowloadButton_Click);
        // 
        // Form1
        // 
        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(104, 54);
        this.Controls.Add(this.dowloadButton);
        this.Name = "Form1";
        this.Text = "Form1";
        this.ResumeLayout(false);

    }

    #endregion
}

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.Run(new Form1());
    }
}

Download do arquivo

O arquivo é baixado no BackgroundWorker thread de trabalho do componente, que executa o DoWork manipulador de eventos. Esse thread é iniciada quando seu código chama o RunWorkerAsync método.

Private Sub backgroundWorker1_DoWork( _
ByVal sender As Object, _
ByVal e As DoWorkEventArgs) _
Handles backgroundWorker1.DoWork

    document = New XmlDocument()

    ' Replace this file name with a valid file name.
    document.Load("http://www.tailspintoys.com/sample.xml")

    ' Uncomment the following line to
    ' simulate a noticeable latency.
    'Thread.Sleep(5000);
End Sub
private void backgroundWorker1_DoWork(
    object sender, 
    DoWorkEventArgs e)
{
    document = new XmlDocument();

    // Replace this file name with a valid file name.
    document.Load(@"http://www.tailspintoys.com/sample.xml");

    // Uncomment the following line to
    // simulate a noticeable latency.
    //Thread.Sleep(5000);
}

Aguardando um BackgroundWorker concluir

The dowloadButton_Click manipulador de eventos Demonstra como aguardar uma BackgroundWorker componente para concluir sua tarefa assíncrono. Use o IsBusy propriedade para determinar se o BackgroundWorker segmento está sendo executado. Se o código está no thread da interface do usuário principal, assim sistema autônomo acontece com o Click evento manipulador, certifique-se de chamar o Application.DoEvents método para manter a interface do usuário respondendo.

Private Sub dowloadButton_Click( _
ByVal sender As Object, _
ByVal e As EventArgs) _
Handles dowloadButton.Click

    ' Start the download operation in the background.
    Me.backgroundWorker1.RunWorkerAsync()

    ' Disable the button for the duration of the download.
    Me.dowloadButton.Enabled = False

    ' Wait for the BackgroundWorker to finish the download.
    While Me.backgroundWorker1.IsBusy
        ' Keep UI messages moving, so the form remains 
        ' responsive during the asynchronous operation.
        Application.DoEvents()
    End While

    ' The download is done, so enable the button.
    Me.dowloadButton.Enabled = True
End Sub
private void dowloadButton_Click(object sender, EventArgs e)
{
    // Start the download operation in the background.
    this.backgroundWorker1.RunWorkerAsync();

    // Disable the button for the duration of the download.
    this.dowloadButton.Enabled = false;

    // Wait for the BackgroundWorker to finish the download.
    while (this.backgroundWorker1.IsBusy)
    {
        // Keep UI messages moving, so the form remains 
        // responsive during the asynchronous operation.
        Application.DoEvents();
    }

    // The download is done, so enable the button.
    this.dowloadButton.Enabled = true;
}

Exibe o resultado

The backgroundWorker1_RunWorkerCompleted método alças a RunWorkerCompleted evento e é chamado quando a operação de plano de fundo é concluída. Ele primeiro verifica o AsyncCompletedEventArgs.Error propriedade, e se isso for null, ele exibe o Sumário do arquivo.

Private Sub backgroundWorker1_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles backgroundWorker1.RunWorkerCompleted
   If e.Error Is Nothing Then
      MessageBox.Show(document.InnerXml, "Download Complete")
   Else
      MessageBox.Show("Failed to download file", "Download failed", MessageBoxButtons.OK, MessageBoxIcon.Error)
   End If
 End Sub
private void backgroundWorker1_RunWorkerCompleted(
    object sender, 
    RunWorkerCompletedEventArgs e)
{
    if (e.Error == null)
    {
        MessageBox.Show(document.InnerXml, "Download Complete");
    }
    else
    {
        MessageBox.Show(
            "Failed to download file", 
            "Download failed", 
            MessageBoxButtons.OK, 
            MessageBoxIcon.Error );
    }
}

Compilando o código

Este exemplo requer:

  • Referências aos assemblies sistema.XML, sistema.Windows.Forms e sistema.desenho.

Para obter informações sobre como criar este exemplo a partir da linha de comando para Visual Basic ou Visual C#, consulte Criando a partir da linha de comando (Visual Basic) ou Linha de comando criando com csc.exe.Você também pode construir este exemplo no Visual Studio colando o código em um novo projeto.

Programação robusta

Sempre verifique o AsyncCompletedEventArgs.Error propriedade no seu RunWorkerCompleted manipulador de eventos antes de tentar acessar o RunWorkerCompletedEventArgs.Result propriedade ou qualquer Outros objeto que foram afetado pela DoWork manipulador de eventos.

Consulte também

Tarefas

Como: Executar uma operação no plano de fundo

Como: Implementar um formulário que usa uma operação em segundo plano

Referência

BackgroundWorker