非同期アプリケーションが完了するのを待たなければ、非同期アプリケーションをキャンセルするために使用できるボタンを設定できます。 このトピックの例に従うことで、1 つの Web サイトまたは Web サイトの一覧のコンテンツをダウンロードするアプリケーションにキャンセル ボタンを追加できます。
この例では、Fine-Tuning Your Async Application (Visual Basic) で説明されている UI を使用します。
注
この例を実行するには、Visual Studio 2012 以降と .NET Framework 4.5 以降がコンピューターにインストールされている必要があります。
タスクを取り消す
最初の例では、[ キャンセル ] ボタンを 1 つのダウンロード タスクに関連付けます。 アプリケーションがコンテンツをダウンロードしている間にボタンを選択すると、ダウンロードは取り消されます。
サンプルをダウンロード
完全な Windows Presentation Foundation (WPF) プロジェクトは 、非同期サンプル: アプリケーションの微調整 からダウンロードし、次の手順に従います。
ダウンロードしたファイルを展開し、Visual Studio を起動します。
メニュー バーで、[ ファイル]、[ 開く]、[ プロジェクト/ソリューション] の順に選択します。
[ プロジェクトを開く ] ダイアログ ボックスで、展開したサンプル コードを保持するフォルダーを開き、AsyncFineTuningVB のソリューション (.sln) ファイルを開きます。
ソリューション エクスプローラーで、CancelATask プロジェクトのショートカット メニューを開き、[スタートアップ プロジェクトとして設定] を選択します。
F5 キーを押してプロジェクトを実行します。
Ctrl キーを押しながら F5 キーを押して、プロジェクトをデバッグせずに実行します。
プロジェクトをダウンロードしない場合は、このトピックの最後にあるMainWindow.xaml.vbファイルを確認できます。
例を構築する
次の変更により、Web サイトをダウンロードするアプリケーションに [キャンセル] ボタンが追加されます。 サンプルをダウンロードまたはビルドしない場合は、このトピックの最後にある「完全な例」セクションで最終製品を確認できます。 アスタリスクは、コード内の変更をマークします。
サンプルを自分でビルドするには、「サンプルのダウンロード」セクションの手順に従いますが、CancelATask ではなく StartUp プロジェクトとして 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
では、HttpClient.GetAsync(String, CancellationToken)型のGetAsync
メソッドのHttpClient オーバーロードを使用して、Web サイトのコンテンツをダウンロードします。ct
のCancellationTokenパラメーター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
プログラムを取り消さないと、次の出力が生成されます。
Ready to download. Length of the downloaded string: 158125.
プログラムがコンテンツのダウンロードを完了する前に [キャンセル] ボタンを選択すると、次の出力が生成されます。
Ready to download. Download canceled.
タスクの一覧を取り消す
前の例を拡張して、同じ CancellationTokenSource
インスタンスを各タスクに関連付けることで、多くのタスクを取り消すことができます。
[キャンセル] ボタンを選択した場合は、まだ完了していないすべてのタスクを取り消します。
サンプルをダウンロード
完全な Windows Presentation Foundation (WPF) プロジェクトは 、非同期サンプル: アプリケーションの微調整 からダウンロードし、次の手順に従います。
ダウンロードしたファイルを展開し、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の代わりにTask<TResult>に変更します。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の参照を追加する必要があることに注意してください。
非同期サンプル: アプリケーションの微調整からプロジェクトをダウンロードできます。
タスクの取り消しの例
次のコードは、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.
こちらも参照ください
.NET