如何:在后台下载文件

来源:互联网 发布:mac numbers使用教程 编辑:程序博客网 时间:2024/04/28 10:23

下载文件是常见任务,通常情况下,最好以单独的线程来运行这项可能很耗时的操作。使用 BackgroundWorker 组件可以用非常少的代码完成此任务。

示例

下面的代码示例演示如何使用 BackgroundWorker 组件从 URL 加载 XML 文件。用户单击“下载”按钮时,Click 事件处理程序将调用 BackgroundWorker 组件的 RunWorkerAsync 方法来启动下载操作。在下载过程中,将禁用该按钮,然后在下载完成后再启用该按钮。MessageBox 将显示文件的内容。

Visual Basic
Imports SystemImports System.Collections.GenericImports System.ComponentModelImports System.DrawingImports System.ThreadingImports System.Windows.FormsImports System.XmlPublic 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 Not (components Is 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 RegionEnd ClassPublic Class Program    ' <summary>    ' The main entry point for the application.    ' </summary>    <STAThread()> _    Shared Sub Main()        Application.EnableVisualStyles()        Application.Run(New Form1())    End SubEnd Class
C#
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());    }}

下载文件

文件下载在 BackgroundWorker 组件的辅助线程上进行,该线程运行 DoWork 事件处理程序。当代码调用 RunWorkerAsync 方法时,将启动此线程。

Visual Basic
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
C#
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);}

等待 BackgroundWorker 完成

dowloadButton_Click 事件处理程序演示如何等待 BackgroundWorker 组件完成它的异步任务。使用 IsBusy 属性可以确定 BackgroundWorker 线程是否仍在运行。如果代码在主 UI 线程上(对于 Click 事件处理程序即是如此),请务必调用 System.Windows.Forms.Application.DoEvents 方法以使用户界面能够响应用户操作。

Visual Basic
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 = TrueEnd Sub
C#
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;}

显示结果

backgroundWorker1_RunWorkerCompleted 方法将处理 RunWorkerCompleted 事件,并在后台操作完成后被调用。它首先检查 System.ComponentModel.AsyncCompletedEventArgs.Error 属性,如果该属性是 null,它将显示文件内容。

Visual Basic
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
C#
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 );    }}

编译代码

  • 请将此代码示例与 System.DrawingSystem.Windows.FormsSystem.Xml 程序集一起编译。

可靠编程

在试图访问 System.ComponentModel.RunWorkerCompletedEventArgs.Result 属性或可能已受 DoWork 事件处理程序影响的任何其他对象之前,一定要在 RunWorkerCompleted 事件处理程序中检查 System.ComponentModel.AsyncCompletedEventArgs.Error 属性。