Gewusst wie: Downloaden einer Datei im Hintergrund
Aktualisiert: November 2007
Das Downloaden von Dateien ist eine häufige Aufgabe. Meistens empfiehlt es sich, diesen vielfach zeitaufwendigen Vorgang in einem separaten Thread auszuführen. Mithilfe der BackgroundWorker-Komponente können Sie diese Aufgabe mit nur wenigen Codezeilen erledigen.
Beispiel
Das folgende Codebeispiel veranschaulicht die Verwendung einer BackgroundWorker-Komponente zum Laden einer XML-Datei über einen URL. Wenn der Benutzer auf die Schaltfläche Download klickt, ruft der Click-Ereignishandler die RunWorkerAsync-Methode einer BackgroundWorker-Komponente auf, um den Downloadvorgang zu starten. Während des Downloads ist die Schaltfläche deaktiviert, und nach Beendigung des Downloads wird sie wieder aktiviert. In MessageBox wird der Inhalt der Datei angezeigt.
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());
}
}
Downloaden der Datei
Die Datei wird im Arbeitsthread der BackgroundWorker-Komponente gedownloadet, der den DoWork-Ereignishandler ausführt. Dieser Thread startet, wenn im Code die RunWorkerAsync-Methode aufgerufen wird.
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);
}
Warten auf die Beendigung von BackgroundWorker
Der dowloadButton_Click-Ereignishandler veranschaulicht, wie gewartet wird, bis die asynchrone Aufgabe einer BackgroundWorker-Komponente beendet ist. Verwenden Sie die IsBusy-Eigenschaft, um zu ermitteln, ob der BackgroundWorker-Thread noch ausgeführt wird. Wenn der Code wie beim Click-Ereignishandler im Hauptthread der Benutzeroberfläche ausgeführt wird, achten Sie darauf, die Application.DoEvents-Methode aufzurufen, damit die Benutzeroberfläche weiterhin reaktionsfähig bleibt.
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;
}
Anzeigen des Ergebnisses
Die backgroundWorker1_RunWorkerCompleted-Methode dient zur Behandlung des RunWorkerCompleted-Ereignisses und wird aufgerufen, wenn der Hintergrundvorgang abgeschlossen ist. Die Methode überprüft zunächst die AsyncCompletedEventArgs.Error-Eigenschaft und zeigt den Inhalt der Datei an, wenn der Eigenschaftenwert null lautet.
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 );
}
}
Kompilieren des Codes
Für dieses Beispiel sind erforderlich:
- Verweise auf die Assemblys System.Drawing, System.Windows.Forms und System.Xml.
Informationen zum Erstellen dieses Beispiels über die Befehlszeile für Visual Basic oder Visual C# finden Sie unterErstellen von der Befehlszeile aus (Visual Basic) und Erstellen über die Befehlszeile mit csc.exe. Sie können dieses Beispiel auch in Visual Studio erstellen, indem Sie den Code in ein neues Projekt einfügen. Gewusst wie: Kompilieren und Ausführen eines vollständigen Windows Forms-Codebeispiels mit Visual Studio
Gewusst wie: Kompilieren und Ausführen eines vollständigen Windows Forms-Codebeispiels mit Visual Studio
Gewusst wie: Kompilieren und Ausführen eines vollständigen Windows Forms-Codebeispiels mit Visual Studio
Gewusst wie: Kompilieren und Ausführen eines vollständigen Windows Forms-Codebeispiels mit Visual Studio
Gewusst wie: Kompilieren und Ausführen eines vollständigen Windows Forms-Codebeispiels mit Visual Studio
Robuste Programmierung
Sie sollten immer die AsyncCompletedEventArgs.Error-Eigenschaft im RunWorkerCompleted-Ereignishandler überprüfen, bevor Sie auf die RunWorkerCompletedEventArgs.Result-Eigenschaft oder auf ein anderes Objekt zugreifen, auf die bzw. das der DoWork-Ereignishandler Einfluss haben kann.
Siehe auch
Aufgaben
Gewusst wie: Ausführen eines Vorgangs im Hintergrund
Gewusst wie: Implementieren eines Formulars, das eine Hintergrundoperation verwendet