Cancel an Async Task or a List of Tasks (Visual Basic) (Отмена асинхронной задачи или списка задач в Visual Basic)
Вы можете настроить кнопку, которая позволит отменить асинхронное приложение в случае, если вы не захотите дожидаться его завершения. Выполнив код в приведенных ниже примерах, вы сможете добавить в приложение кнопку отмены, загружающую содержимое одного веб-сайта или список веб-сайтов.
В примерах используется пользовательский интерфейс, описывающий асинхронное приложение (Visual Basic ).
Примечание.
Для выполнения примеров необходимо, чтобы на компьютере были установлены Visual Studio 2012 или более поздняя версия и .NET Framework 4.5 или более поздняя версия.
Отмена задачи
Код в первом примере связывает кнопку Отмена с отдельной задачей загрузки. Если нажать эту кнопку, когда приложение загружает содержимое, загрузка будет отменена.
Загрузка примера
Вы можете скачать весь проект Windows Presentation Foundation (WPF) со страницы Пример асинхронности. Тонкая настройка приложения, а затем выполнить необходимые действия.
Распакуйте загруженный файл, а затем запустите Visual Studio.
В строке меню выберите Файл, Открыть, Проект/Решение.
В диалоговом окне Открытие проекта откройте папку с примером кода, который вы распаковали, а затем откройте файл решения (с разрешением .sln) для AsyncFineTuningVB.
В обозревателе решений откройте контекстное меню проекта CancelATask и выберите команду Назначить запускаемым проектом.
Нажмите клавишу F5, чтобы запустить проект.
Нажмите сочетание клавиш CTRL+F5, чтобы запустить проект без отладки.
Если вы не хотите скачать проект, вы можете просмотреть MainWindow.xaml.vb файлы в конце этого раздела.
Построение примера
Следующие изменения добавляют кнопку Отмена в приложение, загружающее веб-сайт. Если вы не хотите загружать или собирать пример, просмотрите конечный результат в разделе "Завершенные примеры" в конце раздела. Звездочками отмечены изменения в коде.
Для самостоятельной сборки примера шаг за шагом выполните инструкции в разделе "Загрузка примера", но в качестве запускаемого проекта выберите проект StarterCode, а не CancelATask.
Затем добавьте следующие изменения в файл 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()
В вызове
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 , чтобы скачать содержимое веб-сайта. Передайте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) со страницы Пример асинхронности. Тонкая настройка приложения, а затем выполнить необходимые действия.
Распакуйте загруженный файл, а затем запустите Visual Studio.
В строке меню выберите Файл, Открыть, Проект/Решение.
В диалоговом окне Открытие проекта откройте папку с примером кода, который вы распаковали, а затем откройте файл решения (с разрешением .sln) для AsyncFineTuningVB.
В обозревателе решений откройте контекстное меню проекта CancelAListOfTasks и выберите команду Назначить запускаемым проектом.
Нажмите клавишу F5, чтобы запустить проект.
Нажмите сочетание клавиш CTRL+F5, чтобы запустить проект без отладки.
Если вы не хотите скачать проект, вы можете просмотреть MainWindow.xaml.vb файлы в конце этого раздела.
Построение примера
Для самостоятельного построения примера шаг за шагом выполните инструкции в разделе "Загрузка примера", но выберите CancelATask как запускаемый проект. Добавьте в проект указанные ниже изменения. Звездочками отмечены изменения в программе.
Добавьте метод для создания списка веб-адресов.
' ***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
следующий цикл для обработки каждого веб-адреса в списке.' ***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.
Проекты можно загрузить со страницы Пример асинхронности. Тонкая настройка приложения.
Пример отмены задачи
Следующий код представляет собой полный 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.
См. также
- CancellationTokenSource
- CancellationToken
- Асинхронное программирование с использованием ключевых слов Async и Await (Visual Basic)
- Fine-Tuning Your Async Application (Visual Basic) (Настройка асинхронного приложения (Visual Basic))
- Async Sample: Fine Tuning Your Application (Пример использования async. Тонкая настройка асинхронного приложения)