次の方法で共有


方法 : バックグラウンドでファイルをダウンロードする

更新 : 2007 年 11 月

ファイルのダウンロードは一般的なタスクです。この操作には時間がかかることも多いので、独立したスレッドで実行する方がよい場合があります。BackgroundWorker コンポーネントを使用すると、わずかなコードのみでこのタスクを行うことができます。

使用例

次のコード例は、BackgroundWorker コンポーネントを使用して URL から XML ファイルを読み込む方法を示します。ユーザーが [ダウンロード] ボタンをクリックすると、Click イベント ハンドラによって BackgroundWorker コンポーネントの RunWorkerAsync メソッドが呼び出され、このメソッドによってダウンロードが開始されます。このボタンは、ダウンロード中は無効になり、ダウンロードが完了すると有効になります。MessageBox にファイルの内容が表示されます。

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());
    }
}

ファイルのダウンロード

ファイルは、BackgroundWorker コンポーネントのワーカー スレッドでダウンロードされます。このスレッドは、DoWork イベント ハンドラを実行します。このスレッドは、コードで RunWorkerAsync メソッドが呼び出されると開始します。

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);
}

BackgroundWorker の終了の待機

dowloadButton_Click イベント ハンドラは、BackgroundWorker コンポーネントが非同期タスクを完了するまでの待機方法を示します。IsBusy プロパティを使用すると、BackgroundWorker スレッドがまだ実行中かどうかを確認できます。Click イベント ハンドラの場合のように、コードがメインの UI スレッドにある場合は、Application.DoEvents メソッドを呼び出して UI を応答可能な状態に保つ必要があります。

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;
}

結果の表示

backgroundWorker1_RunWorkerCompleted メソッドは、RunWorkerCompleted イベントを処理するもので、バックグラウンド操作が完了したときに呼び出します。これは、まず AsyncCompletedEventArgs.Error プロパティをチェックし、このプロパティが null の場合はファイルの内容を表示します。

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 );
    }
}

コードのコンパイル方法

この例で必要な要素は次のとおりです。

  • System.Drawing、System.Windows.Forms、System.Xml の各アセンブリへの参照。

Visual Basic または Visual C# のコマンド ラインからこの例をビルドする方法の詳細については、「コマンド ラインからのビルド (Visual Basic)」または「csc.exe を使用したコマンド ラインからのビルド」を参照してください。Visual Studio で新しいプロジェクトにコードを貼り付けてこの例をビルドすることもできます。方法 : 完成した Windows フォーム コードの例を Visual Studio を使ってコンパイルして実行する
方法 : 完成した Windows フォーム コードの例を Visual Studio を使ってコンパイルして実行する
方法 : 完成した Windows フォーム コードの例を Visual Studio を使ってコンパイルして実行する
方法 : 完成した Windows フォーム コードの例を Visual Studio を使ってコンパイルして実行する
方法 : 完成した Windows フォーム コードの例を Visual Studio を使ってコンパイルして実行する

堅牢性の高いプログラム

RunWorkerCompletedEventArgs.Result プロパティ、または DoWork イベント ハンドラの影響を受けている可能性のあるその他のオブジェクトにアクセスする場合は、その前に必ず RunWorkerCompleted イベント ハンドラで AsyncCompletedEventArgs.Error プロパティをチェックしてください。

参照

処理手順

方法 : バックグラウンドで操作を実行する

方法 : バックグラウンド操作を使用するフォームを実装する

参照

BackgroundWorker