如何:在后台下载文件

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

示例

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

Visual Basic
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 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 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
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 = True
End 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 属性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值