次の方法で共有


非同期タスクまたはタスクの一覧を取り消す (Visual Basic)

非同期アプリケーションが完了するのを待たなければ、非同期アプリケーションをキャンセルするために使用できるボタンを設定できます。 このトピックの例に従うことで、1 つの Web サイトまたは Web サイトの一覧のコンテンツをダウンロードするアプリケーションにキャンセル ボタンを追加できます。

この例では、Fine-Tuning Your Async Application (Visual Basic) で説明されている UI を使用します。

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

タスクを取り消す

最初の例では、[ キャンセル ] ボタンを 1 つのダウンロード タスクに関連付けます。 アプリケーションがコンテンツをダウンロードしている間にボタンを選択すると、ダウンロードは取り消されます。

サンプルをダウンロード

完全な Windows Presentation Foundation (WPF) プロジェクトは 、非同期サンプル: アプリケーションの微調整 からダウンロードし、次の手順に従います。

  1. ダウンロードしたファイルを展開し、Visual Studio を起動します。

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

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

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

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

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

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

例を構築する

次の変更により、Web サイトをダウンロードするアプリケーションに [キャンセル] ボタンが追加されます。 サンプルをダウンロードまたはビルドしない場合は、このトピックの最後にある「完全な例」セクションで最終製品を確認できます。 アスタリスクは、コード内の変更をマークします。

サンプルを自分でビルドするには、「サンプルのダウンロード」セクションの手順に従いますが、CancelATask ではなく StartUp プロジェクトとして 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では、HttpClient.GetAsync(String, CancellationToken)型のGetAsync メソッドのHttpClient オーバーロードを使用して、Web サイトのコンテンツをダウンロードします。 ctCancellationTokenパラメーターAccessTheWebAsync、2 番目の引数として渡します。 ユーザーが [キャンセル] ボタンを選択した場合、トークンはメッセージを送信します。

    次のコードは、 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) プロジェクトは 、非同期サンプル: アプリケーションの微調整 からダウンロードし、次の手順に従います。

  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の代わりにTask<TResult>に変更します。

    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の参照を追加する必要があることに注意してください。

非同期サンプル: アプリケーションの微調整からプロジェクトをダウンロードできます。

タスクの取り消しの例

次のコードは、1 つのタスクを取り消す例の完全な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.

こちらも参照ください