Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Das Herunterladen einer Datei ist eine häufige Aufgabe, und es ist häufig nützlich, diesen potenziell zeitaufwendigen Vorgang in einem separaten Thread auszuführen. Verwenden Sie die BackgroundWorker Komponente, um diese Aufgabe mit sehr wenig Code auszuführen.
Beispiel
Im folgenden Codebeispiel wird veranschaulicht, wie eine BackgroundWorker Komponente zum Laden einer XML-Datei aus einer URL verwendet wird. Wenn der Benutzer auf die Schaltfläche " Herunterladen " klickt, ruft der Click Ereignishandler die RunWorkerAsync Methode einer BackgroundWorker Komponente auf, um den Downloadvorgang zu starten. Die Schaltfläche wird für die Dauer des Downloads deaktiviert und nach Abschluss des Downloads aktiviert. A MessageBox zeigt den Inhalt der Datei an.
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 downloadButton;
private ProgressBar progressBar1;
private XmlDocument document = null;
public Form1()
{
InitializeComponent();
// Instantiate BackgroundWorker and attach handlers to its
// DoWork and RunWorkerCompleted events.
backgroundWorker1 = new System.ComponentModel.BackgroundWorker();
backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork);
backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted);
}
private void downloadButton_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.downloadButton.Enabled = false;
// Once you have started the background thread you
// can exit the handler and the application will
// wait until the RunWorkerCompleted event is raised.
// Or if you want to do something else in the main thread,
// such as update a progress bar, you can do so in a loop
// while checking IsBusy to see if the background task is
// still running.
while (this.backgroundWorker1.IsBusy)
{
progressBar1.Increment(1);
// Keep UI messages moving, so the form remains
// responsive during the asynchronous operation.
Application.DoEvents();
}
}
private void backgroundWorker1_DoWork(
object sender,
DoWorkEventArgs e)
{
document = new XmlDocument();
// Uncomment the following line to
// simulate a noticeable latency.
//Thread.Sleep(5000);
// Replace this file name with a valid file name.
document.Load(@"http://www.tailspintoys.com/sample.xml");
}
private void backgroundWorker1_RunWorkerCompleted(
object sender,
RunWorkerCompletedEventArgs e)
{
// Set progress bar to 100% in case it's not already there.
progressBar1.Value = 100;
if (e.Error == null)
{
MessageBox.Show(document.InnerXml, "Download Complete");
}
else
{
MessageBox.Show(
"Failed to download file",
"Download failed",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
// Enable the download button and reset the progress bar.
this.downloadButton.Enabled = true;
progressBar1.Value = 0;
}
#region Windows Form Designer generated code
/// <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);
}
/// <summary>
/// Required method for Designer support
/// </summary>
private void InitializeComponent()
{
this.downloadButton = new System.Windows.Forms.Button();
this.progressBar1 = new System.Windows.Forms.ProgressBar();
this.SuspendLayout();
//
// downloadButton
//
this.downloadButton.Location = new System.Drawing.Point(12, 12);
this.downloadButton.Name = "downloadButton";
this.downloadButton.Size = new System.Drawing.Size(100, 23);
this.downloadButton.TabIndex = 0;
this.downloadButton.Text = "Download file";
this.downloadButton.UseVisualStyleBackColor = true;
this.downloadButton.Click += new System.EventHandler(this.downloadButton_Click);
//
// progressBar1
//
this.progressBar1.Location = new System.Drawing.Point(12, 50);
this.progressBar1.Name = "progressBar1";
this.progressBar1.Size = new System.Drawing.Size(100, 26);
this.progressBar1.TabIndex = 1;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(133, 104);
this.Controls.Add(this.progressBar1);
this.Controls.Add(this.downloadButton);
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());
}
}
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 downloadButton As Button
Private WithEvents progressBar1 As ProgressBar
Private WithEvents backgroundWorker1 As BackgroundWorker
Private document As XmlDocument = Nothing
Public Sub New()
InitializeComponent()
Me.backgroundWorker1 = New System.ComponentModel.BackgroundWorker()
End Sub
Private Sub downloadButton_Click( _
ByVal sender As Object, _
ByVal e As EventArgs) _
Handles downloadButton.Click
' Start the download operation in the background.
Me.backgroundWorker1.RunWorkerAsync()
' Disable the button for the duration of the download.
Me.downloadButton.Enabled = False
' Once you have started the background thread you
' can exit the handler and the application will
' wait until the RunWorkerCompleted event is raised.
' If you want to do something else in the main thread,
' such as update a progress bar, you can do so in a loop
' while checking IsBusy to see if the background task is
' still running.
While Me.backgroundWorker1.IsBusy
progressBar1.Increment(1)
' Keep UI messages moving, so the form remains
' responsive during the asynchronous operation.
Application.DoEvents()
End While
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( _
ByVal sender As Object, _
ByVal e As RunWorkerCompletedEventArgs) _
Handles backgroundWorker1.RunWorkerCompleted
' Set progress bar to 100% in case it isn't already there.
progressBar1.Value = 100
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
' Enable the download button and reset the progress bar.
Me.downloadButton.Enabled = True
progressBar1.Value = 0
End Sub
#Region "Windows Form Designer generated code"
' Required designer variable.
Private components As System.ComponentModel.IContainer = Nothing
' Clean up any resources being used.
' <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing AndAlso (components IsNot Nothing) Then
components.Dispose()
End If
MyBase.Dispose(disposing)
End Sub
' Required method for Designer support - do not modify
' the contents of this method with the code editor.
Private Sub InitializeComponent()
Me.downloadButton = New System.Windows.Forms.Button
Me.progressBar1 = New System.Windows.Forms.ProgressBar
Me.SuspendLayout()
'
'downloadButton
'
Me.downloadButton.Location = New System.Drawing.Point(12, 12)
Me.downloadButton.Name = "downloadButton"
Me.downloadButton.Size = New System.Drawing.Size(100, 23)
Me.downloadButton.TabIndex = 0
Me.downloadButton.Text = "Download file"
Me.downloadButton.UseVisualStyleBackColor = True
'
'progressBar1
'
Me.progressBar1.Location = New System.Drawing.Point(12, 50)
Me.progressBar1.Name = "progressBar1"
Me.progressBar1.Size = New System.Drawing.Size(100, 26)
Me.progressBar1.TabIndex = 1
'
'Form1
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(136, 104)
Me.Controls.Add(Me.downloadButton)
Me.Controls.Add(Me.progressBar1)
Me.Name = "Form1"
Me.Text = "Form1"
Me.ResumeLayout(False)
End Sub
#End Region
End Class
Public Class Program
' The main entry point for the application.
<STAThread()> _
Shared Sub Main()
Application.EnableVisualStyles()
Application.Run(New Form1())
End Sub
End Class
Herunterladen der Datei
Die Datei wird im Workerthread der BackgroundWorker Komponente heruntergeladen, der den DoWork Ereignishandler ausführt. Dieser Thread beginnt, wenn der Code die RunWorkerAsync Methode aufruft.
private void backgroundWorker1_DoWork(
object sender,
DoWorkEventArgs e)
{
document = new XmlDocument();
// Uncomment the following line to
// simulate a noticeable latency.
//Thread.Sleep(5000);
// Replace this file name with a valid file name.
document.Load(@"http://www.tailspintoys.com/sample.xml");
}
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
Warten auf den Abschluss eines BackgroundWorkers
Der downloadButton_Click
Ereignishandler veranschaulicht, wie gewartet wird, bis eine BackgroundWorker Komponente die asynchrone Aufgabe abgeschlossen hat.
Wenn die Anwendung nur auf Ereignisse reagieren soll und im Hauptthread keine Arbeit ausführen soll, während Sie warten, bis der Hintergrundthread abgeschlossen ist, beenden Sie einfach den Handler.
Wenn Sie die Arbeit im Hauptthread fortsetzen möchten, verwenden Sie die IsBusy Eigenschaft, um zu bestimmen, ob der BackgroundWorker Thread noch ausgeführt wird. Im Beispiel wird eine Statusanzeige aktualisiert, während der Download verarbeitet wird. Achten Sie darauf, die Application.DoEvents Methode aufzurufen, um die Ui reaktionsfähig zu halten.
private void downloadButton_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.downloadButton.Enabled = false;
// Once you have started the background thread you
// can exit the handler and the application will
// wait until the RunWorkerCompleted event is raised.
// Or if you want to do something else in the main thread,
// such as update a progress bar, you can do so in a loop
// while checking IsBusy to see if the background task is
// still running.
while (this.backgroundWorker1.IsBusy)
{
progressBar1.Increment(1);
// Keep UI messages moving, so the form remains
// responsive during the asynchronous operation.
Application.DoEvents();
}
}
Private Sub downloadButton_Click( _
ByVal sender As Object, _
ByVal e As EventArgs) _
Handles downloadButton.Click
' Start the download operation in the background.
Me.backgroundWorker1.RunWorkerAsync()
' Disable the button for the duration of the download.
Me.downloadButton.Enabled = False
' Once you have started the background thread you
' can exit the handler and the application will
' wait until the RunWorkerCompleted event is raised.
' If you want to do something else in the main thread,
' such as update a progress bar, you can do so in a loop
' while checking IsBusy to see if the background task is
' still running.
While Me.backgroundWorker1.IsBusy
progressBar1.Increment(1)
' Keep UI messages moving, so the form remains
' responsive during the asynchronous operation.
Application.DoEvents()
End While
End Sub
Anzeigen des Ergebnisses
Die backgroundWorker1_RunWorkerCompleted
Methode behandelt das RunWorkerCompleted Ereignis und wird aufgerufen, wenn der Hintergrundvorgang abgeschlossen ist. Diese Methode überprüft zuerst die AsyncCompletedEventArgs.Error Eigenschaft. Ist AsyncCompletedEventArgs.Error dies null
der Fall, zeigt diese Methode den Inhalt der Datei an. Anschließend wird die Downloadschaltfläche aktiviert, die beim Starten des Downloads deaktiviert wurde, und die Statusleiste wird zurückgesetzt.
private void backgroundWorker1_RunWorkerCompleted(
object sender,
RunWorkerCompletedEventArgs e)
{
// Set progress bar to 100% in case it's not already there.
progressBar1.Value = 100;
if (e.Error == null)
{
MessageBox.Show(document.InnerXml, "Download Complete");
}
else
{
MessageBox.Show(
"Failed to download file",
"Download failed",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
// Enable the download button and reset the progress bar.
this.downloadButton.Enabled = true;
progressBar1.Value = 0;
}
Private Sub backgroundWorker1_RunWorkerCompleted( _
ByVal sender As Object, _
ByVal e As RunWorkerCompletedEventArgs) _
Handles backgroundWorker1.RunWorkerCompleted
' Set progress bar to 100% in case it isn't already there.
progressBar1.Value = 100
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
' Enable the download button and reset the progress bar.
Me.downloadButton.Enabled = True
progressBar1.Value = 0
End Sub
Code kompilieren
In diesem Beispiel ist Folgendes erforderlich:
- Verweise auf die Assemblys "System.Drawing", "System.Windows.Forms" und "System.Xml".
Robuste Programmierung
Überprüfen Sie immer die AsyncCompletedEventArgs.Error Eigenschaft in Ihrem RunWorkerCompleted Ereignishandler, bevor Sie versuchen, auf die RunWorkerCompletedEventArgs.Result Eigenschaft oder ein anderes Objekt zuzugreifen, das möglicherweise vom DoWork Ereignishandler betroffen ist.
Siehe auch
.NET Desktop feedback