方法: 複数の Web 要求を並列実行する (C# および Visual Basic)

非同期のメソッドでは、タスクは作成する場合に呼び出します。待機します。 (Visual Basic) または (C#) 待機します。 の演算子は処理を続行できないメソッドの点のタスクにタスクが終了するまで適用されます。多くの場合、タスクは次の例のように作成しだ待たれます。

Dim result = Await someWebAccessMethodAsync(url)
var result = await someWebAccessMethodAsync(url);

ただし、プログラムに実行するタスクの完了に依存しないそのほかの作業がある場合、タスクの要求からタスクを作成するように分けることができます。

' The following line creates and starts the task.
Dim myTask = someWebAccessMethodAsync(url)

' While the task is running, you can do other work that does not depend
' on the results of the task.
' . . . . .

' The application of Await suspends the rest of this method until the task is 
' complete.
Dim result = Await myTask
// The following line creates and starts the task.
var myTask = someWebAccessMethodAsync(url);

// While the task is running, you can do other work that doesn't depend
// on the results of the task.
// . . . . .

// The application of await suspends the rest of this method until the task is complete.
var result = await myTask;

タスクを起動し、待機することで、他のタスクを開始できます。追加のタスクは暗黙的に並列に実行しますが、追加のスレッドは作成されません。

次のプログラムの開始時には 3 種類の非同期 Web ダウンロードを呼び出す順序で待機します。タスクを作成、待たれる順序で常に終えないプログラムを実行すると、通知します。これらは、作成されるタスクの中に、メソッドの到達する前に、式を終了する可能性がある場合は、先頭。

複数のタスクを同時に呼び出す別の例については、方法: Task.WhenAll を使用してチュートリアルを拡張する (C# および Visual Basic)を参照してください。

このプロジェクトを完了するには、コンピューターにインストールされている Visual Studio 2012 が必要です。詳細については、Microsoft Web サイトを参照してください。

この例のコードは、開発者コード サンプルからダウンロードできます。

プロジェクトを設定するには

  • WPF アプリケーションを設定するには、次の手順を実行します。チュートリアル: Async と Await を使用した Web へのアクセス (C# および Visual Basic)の次の手順の詳細な説明を検索できます。

    • テキスト ボックスとボタンを含む WPF アプリケーションを作成します。ボタン startButtonという名前を付け、テキスト ボックス resultsTextBoxを表示します。

    • System.Net.Httpの参照を追加します。

    • MainWindow.xaml.vb または MainWindow.xaml.cs で、System.Net.Httpの using の Imports のディレクティブまたはステートメントを追加します。

コードを追加するには

  1. デザイン ウィンドウで、MainWindow.xaml は、MainWindow.xaml.vb または MainWindow.xaml.cs の startButton_Click のイベント ハンドラーを作成するには、ボタンをダブルクリックします。または、ボタンをクリックすると、[プロパティ] のウィンドウの 選択した要素のイベント ハンドラー のアイコンを選択し、[クリック] のテキスト ボックスに startButton_Click を入力します。

  2. 次のコードをコピーし、MainWindow.xaml.vb または MainWindow.xaml.cs の startButton_Click の本体に貼り付けます。

    resultsTextBox.Clear()
    Await CreateMultipleTasksAsync()
    resultsTextBox.Text &= vbCrLf & "Control returned to button1_Click."
    
    resultsTextBox.Clear();
    await CreateMultipleTasksAsync();
    resultsTextBox.Text += "\r\n\r\nControl returned to startButton_Click.\r\n";
    

    コードは、アプリケーションを呼び出す非同期メソッド、CreateMultipleTasksAsyncを呼び出します。

  3. プロジェクトのサポートに次のメソッドを追加します:

    • ProcessURLAsync はバイト配列としてサイトのコンテンツをダウンロードするに HttpClient のメソッドを使用します。サポート メソッド、ProcessURLAsync は、配列の長さを表示して返します。

    • DisplayResults は、各 URL のバイト配列のバイト数を表示します。このコントロールは、各タスクがダウンロードされいつ完了したかを示します。

    次のメソッドをコピーし、MainWindow.xaml.vb または MainWindow.xaml.cs の startButton_Click のイベント ハンドラーの後に貼り付けます。

    Private Async Function ProcessURLAsync(url As String, client As HttpClient) As Task(Of Integer)
    
        Dim byteArray = Await client.GetByteArrayAsync(url)
        DisplayResults(url, byteArray)
        Return byteArray.Length
    End Function
    
    
    Private Sub DisplayResults(url As String, content As Byte())
    
        ' Display the length of each website. The string format 
        ' is designed to be used with a monospaced font, such as
        ' Lucida Console or Global Monospace.
        Dim bytes = content.Length
        ' Strip off the "http://".
        Dim displayURL = url.Replace("http://", "")
        resultsTextBox.Text &= String.Format(vbCrLf & "{0,-58} {1,8}", displayURL, bytes)
    End Sub
    
    async Task<int> ProcessURLAsync(string url, HttpClient client)
    {
        var byteArray = await client.GetByteArrayAsync(url);
        DisplayResults(url, byteArray);
        return byteArray.Length;
    }
    
    
    private void DisplayResults(string url, byte[] content)
    {
        // Display the length of each website. The string format 
        // is designed to be used with a monospaced font, such as
        // Lucida Console or Global Monospace.
        var bytes = content.Length;
        // Strip off the "http://".
        var displayURL = url.Replace("http://", "");
        resultsTextBox.Text += string.Format("\n{0,-58} {1,8}", displayURL, bytes);
    }
    
  4. 最後に、次の手順を実行するメソッド CreateMultipleTasksAsyncを定義します。

    • メソッドは、ProcessURLAsyncのアクセス方法 GetByteArrayAsync を必要とする HttpClient のオブジェクトを宣言します。

    • メソッドは TResult が整数型である Task<TResult>の 3 個のタスクを作成および開始します。各タスクが終了すると、DisplayResults はタスクのダウンロード コンテンツの URL と長さが表示されます。タスクは非同期的に実行されるため、結果を表示する順序は、宣言された順序と異なる場合があります。

    • メソッドは、各タスクの完了を待機します。Await または await の各演算子は、予期したタスクが終了するまで CreateMultipleTasksAsync の実行を中断します。演算子は、呼び出しから、完了した各タスクから ProcessURLAsync に戻り値を取得します。

    • タスクが完了したら、整数値が取得されたメソッドは、サイトの長さの合計を入力し、結果を表示します。

    次のメソッドをコピーし、ソリューションに貼り付けます。

    Private Async Function CreateMultipleTasksAsync() As Task
    
        ' Declare an HttpClient object, and increase the buffer size. The
        ' default buffer size is 65,536.
        Dim client As HttpClient =
            New HttpClient() With {.MaxResponseContentBufferSize = 1000000}
    
        ' Create and start the tasks. As each task finishes, DisplayResults 
        ' displays its length.
        Dim download1 As Task(Of Integer) =
            ProcessURLAsync("https://msdn.microsoft.com", client)
        Dim download2 As Task(Of Integer) =
            ProcessURLAsync("https://msdn.microsoft.com/en-us/library/hh156528(VS.110).aspx", client)
        Dim download3 As Task(Of Integer) =
            ProcessURLAsync("https://msdn.microsoft.com/en-us/library/67w7t67f.aspx", client)
    
        ' Await each task.
        Dim length1 As Integer = Await download1
        Dim length2 As Integer = Await download2
        Dim length3 As Integer = Await download3
    
        Dim total As Integer = length1 + length2 + length3
    
        ' Display the total count for all of the websites.
        resultsTextBox.Text &= String.Format(vbCrLf & vbCrLf &
                                             "Total bytes returned:  {0}" & vbCrLf, total)
    End Function
    
    private async Task CreateMultipleTasksAsync()
    {
        // Declare an HttpClient object, and increase the buffer size. The
        // default buffer size is 65,536.
        HttpClient client =
            new HttpClient() { MaxResponseContentBufferSize = 1000000 };
    
        // Create and start the tasks. As each task finishes, DisplayResults 
        // displays its length.
        Task<int> download1 = 
            ProcessURLAsync("https://msdn.microsoft.com", client);
        Task<int> download2 = 
            ProcessURLAsync("https://msdn.microsoft.com/en-us/library/hh156528(VS.110).aspx", client);
        Task<int> download3 = 
            ProcessURLAsync("https://msdn.microsoft.com/en-us/library/67w7t67f.aspx", client);
    
        // Await each task.
        int length1 = await download1;
        int length2 = await download2;
        int length3 = await download3;
    
        int total = length1 + length2 + length3;
    
        // Display the total count for the downloaded websites.
        resultsTextBox.Text +=
            string.Format("\r\n\r\nTotal bytes returned:  {0}\r\n", total);
    }
    
  5. プログラムを実行するには、F5 キーを選択し、を [開始] のボタンをクリックします。

    プログラムを 3 のタスクが同じ順序で常に完了しないこと、および終了順序は必ず、作成され、待たれる順序でないことを確認する複数回実行します。

使用例

ここまでの例をすべて含んだコードを次に示します。

' Add the following Imports statements, and add a reference for System.Net.Http.
Imports System.Net.Http


Class MainWindow

    Async Sub startButton_Click(sender As Object, e As RoutedEventArgs) Handles startButton.Click
        resultsTextBox.Clear()
        Await CreateMultipleTasksAsync()
        resultsTextBox.Text &= vbCrLf & "Control returned to button1_Click."
    End Sub


    Private Async Function CreateMultipleTasksAsync() As Task

        ' Declare an HttpClient object, and increase the buffer size. The
        ' default buffer size is 65,536.
        Dim client As HttpClient =
            New HttpClient() With {.MaxResponseContentBufferSize = 1000000}

        ' Create and start the tasks. As each task finishes, DisplayResults 
        ' displays its length.
        Dim download1 As Task(Of Integer) =
            ProcessURLAsync("https://msdn.microsoft.com", client)
        Dim download2 As Task(Of Integer) =
            ProcessURLAsync("https://msdn.microsoft.com/en-us/library/hh156528(VS.110).aspx", client)
        Dim download3 As Task(Of Integer) =
            ProcessURLAsync("https://msdn.microsoft.com/en-us/library/67w7t67f.aspx", client)

        ' Await each task.
        Dim length1 As Integer = Await download1
        Dim length2 As Integer = Await download2
        Dim length3 As Integer = Await download3

        Dim total As Integer = length1 + length2 + length3

        ' Display the total count for all of the websites.
        resultsTextBox.Text &= String.Format(vbCrLf & vbCrLf &
                                             "Total bytes returned:  {0}" & vbCrLf, total)
    End Function


    Private Async Function ProcessURLAsync(url As String, client As HttpClient) As Task(Of Integer)

        Dim byteArray = Await client.GetByteArrayAsync(url)
        DisplayResults(url, byteArray)
        Return byteArray.Length
    End Function


    Private Sub DisplayResults(url As String, content As Byte())

        ' Display the length of each website. The string format 
        ' is designed to be used with a monospaced font, such as
        ' Lucida Console or Global Monospace.
        Dim bytes = content.Length
        ' Strip off the "http://".
        Dim displayURL = url.Replace("http://", "")
        resultsTextBox.Text &= String.Format(vbCrLf & "{0,-58} {1,8}", displayURL, bytes)
    End Sub
End Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

// Add the following using directive, and add a reference for System.Net.Http.
using System.Net.Http;


namespace AsyncExample_MultipleTasks
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private async void startButton_Click(object sender, RoutedEventArgs e)
        {
            resultsTextBox.Clear();
            await CreateMultipleTasksAsync();
            resultsTextBox.Text += "\r\n\r\nControl returned to startButton_Click.\r\n";
        }


        private async Task CreateMultipleTasksAsync()
        {
            // Declare an HttpClient object, and increase the buffer size. The
            // default buffer size is 65,536.
            HttpClient client =
                new HttpClient() { MaxResponseContentBufferSize = 1000000 };

            // Create and start the tasks. As each task finishes, DisplayResults 
            // displays its length.
            Task<int> download1 = 
                ProcessURLAsync("https://msdn.microsoft.com", client);
            Task<int> download2 = 
                ProcessURLAsync("https://msdn.microsoft.com/en-us/library/hh156528(VS.110).aspx", client);
            Task<int> download3 = 
                ProcessURLAsync("https://msdn.microsoft.com/en-us/library/67w7t67f.aspx", client);

            // Await each task.
            int length1 = await download1;
            int length2 = await download2;
            int length3 = await download3;

            int total = length1 + length2 + length3;

            // Display the total count for the downloaded websites.
            resultsTextBox.Text +=
                string.Format("\r\n\r\nTotal bytes returned:  {0}\r\n", total);
        }


        async Task<int> ProcessURLAsync(string url, HttpClient client)
        {
            var byteArray = await client.GetByteArrayAsync(url);
            DisplayResults(url, byteArray);
            return byteArray.Length;
        }


        private void DisplayResults(string url, byte[] content)
        {
            // Display the length of each website. The string format 
            // is designed to be used with a monospaced font, such as
            // Lucida Console or Global Monospace.
            var bytes = content.Length;
            // Strip off the "http://".
            var displayURL = url.Replace("http://", "");
            resultsTextBox.Text += string.Format("\n{0,-58} {1,8}", displayURL, bytes);
        }
    }
}

参照

処理手順

チュートリアル: Async と Await を使用した Web へのアクセス (C# および Visual Basic)

方法: Task.WhenAll を使用してチュートリアルを拡張する (C# および Visual Basic)

概念

Async および Await を使用した非同期プログラミング (C# および Visual Basic)