非同期タスクまたはタスクの一覧のキャンセル (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」(非同期のサンプル: アプリケーションの微調整) からダウンロードできます。その後、次の手順に従います。
ダウンロードしたファイルを圧縮解除し、Visual Studio を起動します。
メニュー バーで [ファイル] 、 [開く] 、 [プロジェクト/ソリューション] の順に選択します。
[プロジェクトを開く] ダイアログ ボックスで、圧縮解除したサンプル コードを含むフォルダーを開き、AsyncFineTuningVB 用のソリューション (.sln) ファイルを開きます。
ソリューション エクスプローラーで、CancelATask プロジェクトのショートカット メニューを開き、 [スタートアップ プロジェクトに設定] をクリックします。
F5 キーを押してプロジェクトを実行します。
Ctrl + F5 キーを押して、デバッグを行わずにプロジェクトを実行します。
プロジェクトをダウンロードしない場合は、このトピックの最後の MainWindow.xaml.vb ファイルをレビューできます。
例のビルド
次の変更は、Web サイトをダウンロードするアプリケーションにキャンセル ボタンを追加します。 この例のダウンロードまたはビルドをしない場合は、このトピックの最後にある「コード例全体」のセクションで最終製品をレビューできます。 アスタリスクはコードの変更点を示しています。
この例を自分でビルドするには、「例をダウンロードする」のセクションの詳細な手順の指示に従いますが、 [スタートアップ プロジェクト] として、 [CancelATask] の代わりに [StarterCode] を選択します。
次の変更点をプロジェクトの MainWindow.xaml.vb ファイルに追加します。
アクセスするすべてのメソッドのスコープである
CancellationTokenSource
変数、cts
を宣言します。Class MainWindow ' ***Declare a System.Threading.CancellationTokenSource. Dim cts As CancellationTokenSource
次のようなキャンセル ボタンのイベント ハンドラーのコードを追加します。 ユーザーが取り消しを要求すると、イベント ハンドラーは 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
開始ボタン
startButton_Click
のためのイベント ハンドラーに次の変更を行います。CancellationTokenSource
、cts
をインスタンス化します。' ***Instantiate the CancellationTokenSource. cts = New CancellationTokenSource()
指定された Web サイトのコンテンツをダウンロードする
AccessTheWebAsync
の呼び出しでは、引数として CancellationTokenSource.Token のcts
プロパティを送ります。 取り消しが要求されると、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
AccessTheWebAsync
では、Web サイトのコンテンツをダウンロードするために HttpClient 型のGetAsync
メソッドの HttpClient.GetAsync(String, CancellationToken) オーバーロードを使用します。 2 番目の引数として、ct
の CancellationToken パラメーターである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
プログラムの取り消しをしない場合、次の出力を生成します。
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」(非同期のサンプル: アプリケーションの微調整) からダウンロードできます。その後、次の手順に従います。
ダウンロードしたファイルを圧縮解除し、Visual Studio を起動します。
メニュー バーで [ファイル] 、 [開く] 、 [プロジェクト/ソリューション] の順に選択します。
[プロジェクトを開く] ダイアログ ボックスで、圧縮解除したサンプル コードを含むフォルダーを開き、AsyncFineTuningVB 用のソリューション (.sln) ファイルを開きます。
ソリューション エクスプローラーで、CancelAListOfTasks プロジェクトのショートカット メニューを開き、 [スタートアップ プロジェクトに設定] をクリックします。
F5 キーを押してプロジェクトを実行します。
Ctrl + F5 キーを押して、デバッグを行わずにプロジェクトを実行します。
プロジェクトをダウンロードしない場合は、このトピックの最後の MainWindow.xaml.vb ファイルをレビューできます。
例のビルド
この例を自分で拡張するには、「例をダウンロードする」のセクションの詳細な手順の指示に従いますが、 [スタートアップ プロジェクト] として CancelATask を選択します。 次の変更点をプロジェクトに追加します。 アスタリスクはプログラムの変更点を示しています。
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
AccessTheWebAsync
のメソッドを呼び出します。' ***Call SetUpURLList to make a list of web addresses. Dim urlList As List(Of String) = SetUpURLList()
次のループを
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
AccessTheWebAsync
は長さを表示するため、メソッドは何も返す必要はありません。 return ステートメントを削除し、メソッドの戻り値の型を Task<TResult> ではなく Task に変更します。Async Function AccessTheWebAsync(ct As CancellationToken) As Task
式の代わりにステートメントを使って、
startButton_Click
からメソッドを呼び出します。Await AccessTheWebAsync(cts.Token)
プログラムの取り消しをしない場合、次の出力を生成します。
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.
関連項目
.NET