次の方法で共有


非同期タスクまたはタスクの一覧のキャンセル (Visual Basic)

非同期のアプリケーションが終了するまで待機しない場合、それを取り消すために使用できるボタンを設定できます。 このトピックの例に従うと、1 つの Web サイトのコンテンツまたは Web サイトのリストをダウンロードするアプリケーションにキャンセル ボタンを追加できます。

例では、「非同期アプリケーションの微調整 (Visual Basic)」で説明している UI を使用しています。

注意

この例を実行するには、コンピューターに Visual Studio 2012 以降および .NET Framework 4.5 以降がインストールされている必要があります。

タスクのキャンセル

最初の例では、キャンセル ボタンを単一のダウンロード タスクと関連付けます。 アプリケーションがコンテンツをダウンロード中にボタンをクリックすると、ダウンロードは取り消されます。

例をダウンロードする

完全な Windows Presentation Foundation (WPF) プロジェクトは、「Async Sample: Fine Tuning Your Application」(非同期のサンプル: アプリケーションの微調整) からダウンロードできます。その後、次の手順に従います。

  1. ダウンロードしたファイルを圧縮解除し、Visual Studio を起動します。

  2. メニュー バーで [ファイル][開く][プロジェクト/ソリューション] の順に選択します。

  3. [プロジェクトを開く] ダイアログ ボックスで、圧縮解除したサンプル コードを含むフォルダーを開き、AsyncFineTuningVB 用のソリューション (.sln) ファイルを開きます。

  4. ソリューション エクスプローラーで、CancelATask プロジェクトのショートカット メニューを開き、 [スタートアップ プロジェクトに設定] をクリックします。

  5. F5 キーを押してプロジェクトを実行します。

    Ctrl + F5 キーを押して、デバッグを行わずにプロジェクトを実行します。

プロジェクトをダウンロードしない場合は、このトピックの最後の MainWindow.xaml.vb ファイルをレビューできます。

例のビルド

次の変更は、Web サイトをダウンロードするアプリケーションにキャンセル ボタンを追加します。 この例のダウンロードまたはビルドをしない場合は、このトピックの最後にある「コード例全体」のセクションで最終製品をレビューできます。 アスタリスクはコードの変更点を示しています。

この例を自分でビルドするには、「例をダウンロードする」のセクションの詳細な手順の指示に従いますが、 [スタートアップ プロジェクト] として、 [CancelATask] の代わりに [StarterCode] を選択します。

次の変更点をプロジェクトの MainWindow.xaml.vb ファイルに追加します。

  1. アクセスするすべてのメソッドのスコープである CancellationTokenSource 変数、cts を宣言します。

    Class MainWindow
    
        ' ***Declare a System.Threading.CancellationTokenSource.
        Dim cts As CancellationTokenSource
    
  2. 次のようなキャンセル ボタンのイベント ハンドラーのコードを追加します。 ユーザーが取り消しを要求すると、イベント ハンドラーは CancellationTokenSource.Cancel メソッドを使って cts に通知します。

    ' ***Add an event handler for the Cancel button.
    Private Sub cancelButton_Click(sender As Object, e As RoutedEventArgs)
    
        If cts IsNot Nothing Then
            cts.Cancel()
        End If
    End Sub
    
  3. 開始ボタン startButton_Click のためのイベント ハンドラーに次の変更を行います。

    • CancellationTokenSourcects をインスタンス化します。

      ' ***Instantiate the CancellationTokenSource.
      cts = New CancellationTokenSource()
      
    • 指定された Web サイトのコンテンツをダウンロードする AccessTheWebAsync の呼び出しでは、引数として CancellationTokenSource.Tokencts プロパティを送ります。 取り消しが要求されると、Token プロパティがメッセージを伝達します。 ユーザーがダウンロード操作の取り消しを選択するとメッセージを表示する catch ブロックを追加します。 次のコードは変更点を示しています。

      Try
          ' ***Send a token to carry the message if cancellation is requested.
          Dim contentLength As Integer = Await AccessTheWebAsync(cts.Token)
      
          resultsTextBox.Text &=
              vbCrLf & $"Length of the downloaded string: {contentLength}." & vbCrLf
      
          ' *** If cancellation is requested, an OperationCanceledException results.
      Catch ex As OperationCanceledException
          resultsTextBox.Text &= vbCrLf & "Download canceled." & vbCrLf
      
      Catch ex As Exception
          resultsTextBox.Text &= vbCrLf & "Download failed." & vbCrLf
      End Try
      
  4. AccessTheWebAsync では、Web サイトのコンテンツをダウンロードするために HttpClient 型の GetAsync メソッドの HttpClient.GetAsync(String, CancellationToken) オーバーロードを使用します。 2 番目の引数として、ctCancellationToken パラメーターである AccessTheWebAsync を渡します。 ユーザーがキャンセル ボタンをクリックすると、トークンがメッセージを送信します。

    次のコードは、AccessTheWebAsync の変更点を示しています。

    ' ***Provide a parameter for the CancellationToken.
    Async Function AccessTheWebAsync(ct As CancellationToken) As Task(Of Integer)
    
        Dim client As HttpClient = New HttpClient()
    
        resultsTextBox.Text &= vbCrLf & "Ready to download." & vbCrLf
    
        ' You might need to slow things down to have a chance to cancel.
        Await Task.Delay(250)
    
        ' GetAsync returns a Task(Of HttpResponseMessage).
        ' ***The ct argument carries the message if the Cancel button is chosen.
        Dim response As HttpResponseMessage = Await client.GetAsync("https://msdn.microsoft.com/library/dd470362.aspx", ct)
    
        ' Retrieve the website contents from the HttpResponseMessage.
        Dim urlContents As Byte() = Await response.Content.ReadAsByteArrayAsync()
    
        ' The result of the method is the length of the downloaded website.
        Return urlContents.Length
    End Function
    
  5. プログラムの取り消しをしない場合、次の出力を生成します。

    Ready to download.
    Length of the downloaded string: 158125.
    

    プログラムがコンテンツのダウンロードを終了する前にキャンセル ボタンをクリックすると、プログラムは次の出力を生成します。

    Ready to download.
    Download canceled.
    

タスクの一覧を取り消す

前の例を拡張すると、同じ CancellationTokenSource のインスタンスを各タスクに関連付けることによって、多数のタスクを取り消すことができます。 キャンセル ボタンをクリックすると、完了していないすべてのタスクを取り消します。

例をダウンロードする

完全な Windows Presentation Foundation (WPF) プロジェクトは、「Async Sample: Fine Tuning Your Application」(非同期のサンプル: アプリケーションの微調整) からダウンロードできます。その後、次の手順に従います。

  1. ダウンロードしたファイルを圧縮解除し、Visual Studio を起動します。

  2. メニュー バーで [ファイル][開く][プロジェクト/ソリューション] の順に選択します。

  3. [プロジェクトを開く] ダイアログ ボックスで、圧縮解除したサンプル コードを含むフォルダーを開き、AsyncFineTuningVB 用のソリューション (.sln) ファイルを開きます。

  4. ソリューション エクスプローラーで、CancelAListOfTasks プロジェクトのショートカット メニューを開き、 [スタートアップ プロジェクトに設定] をクリックします。

  5. F5 キーを押してプロジェクトを実行します。

    Ctrl + F5 キーを押して、デバッグを行わずにプロジェクトを実行します。

プロジェクトをダウンロードしない場合は、このトピックの最後の MainWindow.xaml.vb ファイルをレビューできます。

例のビルド

この例を自分で拡張するには、「例をダウンロードする」のセクションの詳細な手順の指示に従いますが、 [スタートアップ プロジェクト] として CancelATask を選択します。 次の変更点をプロジェクトに追加します。 アスタリスクはプログラムの変更点を示しています。

  1. Web アドレスのリストを作成するメソッドを追加します。

    ' ***Add a method that creates a list of web addresses.
    Private Function SetUpURLList() As List(Of String)
    
        Dim urls = New List(Of String) From
            {
                "https://msdn.microsoft.com",
                "https://msdn.microsoft.com/library/hh290138.aspx",
                "https://msdn.microsoft.com/library/hh290140.aspx",
                "https://msdn.microsoft.com/library/dd470362.aspx",
                "https://msdn.microsoft.com/library/aa578028.aspx",
                "https://msdn.microsoft.com/library/ms404677.aspx",
                "https://msdn.microsoft.com/library/ff730837.aspx"
            }
        Return urls
    End Function
    
  2. AccessTheWebAsync のメソッドを呼び出します。

    ' ***Call SetUpURLList to make a list of web addresses.
    Dim urlList As List(Of String) = SetUpURLList()
    
  3. 次のループを AccessTheWebAsync に追加して、リストの各 Web アドレスを処理します。

    ' ***Add a loop to process the list of web addresses.
    For Each url In urlList
        ' GetAsync returns a Task(Of HttpResponseMessage).
        ' Argument ct carries the message if the Cancel button is chosen.
        ' ***Note that the Cancel button can cancel all remaining downloads.
        Dim response As HttpResponseMessage = Await client.GetAsync(url, ct)
    
        ' Retrieve the website contents from the HttpResponseMessage.
        Dim urlContents As Byte() = Await response.Content.ReadAsByteArrayAsync()
    
        resultsTextBox.Text &=
            vbCrLf & $"Length of the downloaded string: {urlContents.Length}." & vbCrLf
    Next
    
  4. AccessTheWebAsync は長さを表示するため、メソッドは何も返す必要はありません。 return ステートメントを削除し、メソッドの戻り値の型を Task<TResult> ではなく Task に変更します。

    Async Function AccessTheWebAsync(ct As CancellationToken) As Task
    

    式の代わりにステートメントを使って、startButton_Click からメソッドを呼び出します。

    Await AccessTheWebAsync(cts.Token)
    
  5. プログラムの取り消しをしない場合、次の出力を生成します。

    Length of the downloaded string: 35939.
    
    Length of the downloaded string: 237682.
    
    Length of the downloaded string: 128607.
    
    Length of the downloaded string: 158124.
    
    Length of the downloaded string: 204890.
    
    Length of the downloaded string: 175488.
    
    Length of the downloaded string: 145790.
    
    Downloads complete.
    

    ダウンロードが完了する前にキャンセル ボタンをクリックすると、出力には取り消しの前に完了したダウンロードの長さが含まれています。

    Length of the downloaded string: 35939.
    
    Length of the downloaded string: 237682.
    
    Length of the downloaded string: 128607.
    
    Downloads canceled.
    

コード例全体

次のセクションには、前の例の各コードが含まれています。 System.Net.Http の参照を追加する必要があることに注意してください。

プロジェクトは、「Async Sample:Fine Tuning Your Application」 (非同期のサンプル: アプリケーションの微調整) からダウンロードできます。

タスクを取り消す例

次のコードは、単一のタスクを取り消す例での MainWindow.xaml.vb ファイルの全体です。

' Add an Imports directive and a reference for System.Net.Http.
Imports System.Net.Http

' Add the following Imports directive for System.Threading.
Imports System.Threading

Class MainWindow

    ' ***Declare a System.Threading.CancellationTokenSource.
    Dim cts As CancellationTokenSource

    Private Async Sub startButton_Click(sender As Object, e As RoutedEventArgs)
        ' ***Instantiate the CancellationTokenSource.
        cts = New CancellationTokenSource()

        resultsTextBox.Clear()

        Try
            ' ***Send a token to carry the message if cancellation is requested.
            Dim contentLength As Integer = Await AccessTheWebAsync(cts.Token)

            resultsTextBox.Text &=
                vbCrLf & $"Length of the downloaded string: {contentLength}." & vbCrLf

            ' *** If cancellation is requested, an OperationCanceledException results.
        Catch ex As OperationCanceledException
            resultsTextBox.Text &= vbCrLf & "Download canceled." & vbCrLf

        Catch ex As Exception
            resultsTextBox.Text &= vbCrLf & "Download failed." & vbCrLf
        End Try

        ' ***Set the CancellationTokenSource to Nothing when the download is complete.
        cts = Nothing
    End Sub

    ' ***Add an event handler for the Cancel button.
    Private Sub cancelButton_Click(sender As Object, e As RoutedEventArgs)

        If cts IsNot Nothing Then
            cts.Cancel()
        End If
    End Sub

    ' ***Provide a parameter for the CancellationToken.
    Async Function AccessTheWebAsync(ct As CancellationToken) As Task(Of Integer)

        Dim client As HttpClient = New HttpClient()

        resultsTextBox.Text &=
            vbCrLf & "Ready to download." & vbCrLf

        ' You might need to slow things down to have a chance to cancel.
        Await Task.Delay(250)

        ' GetAsync returns a Task(Of HttpResponseMessage).
        ' ***The ct argument carries the message if the Cancel button is chosen.
        Dim response As HttpResponseMessage = Await client.GetAsync("https://msdn.microsoft.com/library/dd470362.aspx", ct)

        ' Retrieve the website contents from the HttpResponseMessage.
        Dim urlContents As Byte() = Await response.Content.ReadAsByteArrayAsync()

        ' The result of the method is the length of the downloaded website.
        Return urlContents.Length
    End Function
End Class

' Output for a successful download:

' Ready to download.

' Length of the downloaded string: 158125.

' Or, if you cancel:

' Ready to download.

' Download canceled.

タスクの一覧を取り消す例

次のコードは、タスクの一覧を取り消す例での MainWindow.xaml.vb ファイルの全体です。

' Add an Imports directive and a reference for System.Net.Http.
Imports System.Net.Http

' Add the following Imports directive for System.Threading.
Imports System.Threading

Class MainWindow

    ' Declare a System.Threading.CancellationTokenSource.
    Dim cts As CancellationTokenSource

    Private Async Sub startButton_Click(sender As Object, e As RoutedEventArgs)

        ' Instantiate the CancellationTokenSource.
        cts = New CancellationTokenSource()

        resultsTextBox.Clear()

        Try
            ' ***AccessTheWebAsync returns a Task, not a Task(Of Integer).
            Await AccessTheWebAsync(cts.Token)
            '  ***Small change in the display lines.
            resultsTextBox.Text &= vbCrLf & "Downloads complete."

        Catch ex As OperationCanceledException
            resultsTextBox.Text &= vbCrLf & "Downloads canceled." & vbCrLf

        Catch ex As Exception
            resultsTextBox.Text &= vbCrLf & "Downloads failed." & vbCrLf
        End Try

        ' Set the CancellationTokenSource to Nothing when the download is complete.
        cts = Nothing
    End Sub

    ' Add an event handler for the Cancel button.
    Private Sub cancelButton_Click(sender As Object, e As RoutedEventArgs)

        If cts IsNot Nothing Then
            cts.Cancel()
        End If
    End Sub

    ' Provide a parameter for the CancellationToken.
    ' ***Change the return type to Task because the method has no return statement.
    Async Function AccessTheWebAsync(ct As CancellationToken) As Task

        Dim client As HttpClient = New HttpClient()

        ' ***Call SetUpURLList to make a list of web addresses.
        Dim urlList As List(Of String) = SetUpURLList()

        ' ***Add a loop to process the list of web addresses.
        For Each url In urlList
            ' GetAsync returns a Task(Of HttpResponseMessage).
            ' Argument ct carries the message if the Cancel button is chosen.
            ' ***Note that the Cancel button can cancel all remaining downloads.
            Dim response As HttpResponseMessage = Await client.GetAsync(url, ct)

            ' Retrieve the website contents from the HttpResponseMessage.
            Dim urlContents As Byte() = Await response.Content.ReadAsByteArrayAsync()

            resultsTextBox.Text &=
                vbCrLf & $"Length of the downloaded string: {urlContents.Length}." & vbCrLf
        Next
    End Function

    ' ***Add a method that creates a list of web addresses.
    Private Function SetUpURLList() As List(Of String)

        Dim urls = New List(Of String) From
            {
                "https://msdn.microsoft.com",
                "https://msdn.microsoft.com/library/hh290138.aspx",
                "https://msdn.microsoft.com/library/hh290140.aspx",
                "https://msdn.microsoft.com/library/dd470362.aspx",
                "https://msdn.microsoft.com/library/aa578028.aspx",
                "https://msdn.microsoft.com/library/ms404677.aspx",
                "https://msdn.microsoft.com/library/ff730837.aspx"
            }
        Return urls
    End Function

End Class

' Output if you do not choose to cancel:

' Length of the downloaded string: 35939.

' Length of the downloaded string: 237682.

' Length of the downloaded string: 128607.

' Length of the downloaded string: 158124.

' Length of the downloaded string: 204890.

' Length of the downloaded string: 175488.

' Length of the downloaded string: 145790.

' Downloads complete.

'  Sample output if you choose to cancel:

' Length of the downloaded string: 35939.

' Length of the downloaded string: 237682.

' Length of the downloaded string: 128607.

' Downloads canceled.

関連項目