Поделиться через


Отмена асинхронной задачи или списка задач (Visual Basic)

Вы можете настроить кнопку, которую можно использовать для отмены асинхронного приложения, если вы не хотите ждать завершения. Следуя примерам в этом разделе, можно добавить кнопку отмены в приложение, которое скачивает содержимое одного веб-сайта или список веб-сайтов.

В примерах используется пользовательский интерфейс, который Fine-Tuning описан в приложении Your Async Application (Visual Basic).

Замечание

Для выполнения примеров необходимо установить Visual Studio 2012 или более поздней версии и .NET Framework 4.5 или более поздней версии на компьютере.

Отмена задачи

Первый пример связывает кнопку "Отмена " с одной задачей скачивания. Если вы выберете кнопку при скачивании содержимого приложения, скачивание будет отменено.

Скачивание примера

Вы можете скачать полный проект Windows Presentation Foundation (WPF) из примера Async: настройки вашего приложения и затем выполните следующие действия.

  1. Распакуйте скачанный файл и запустите Visual Studio.

  2. В строке меню выберите "Файл", "Открыть", "Проект или решение".

  3. В диалоговом окне "Открыть проект" откройте папку, содержащую пример кода, который вы распаковали, а затем откройте файл решения (.sln) для AsyncFineTuningVB.

  4. В обозревателе решений откройте контекстное меню для проекта CancelATask , а затем выберите "Задать в качестве проекта запуска".

  5. Выберите клавишу F5 для запуска проекта.

    Выберите клавиши CTRL+F5, чтобы запустить проект без отладки.

Если вы не хотите скачать проект, вы можете просмотреть MainWindow.xaml.vb файлы в конце этого раздела.

Создание примера

Следующие изменения добавляют кнопку "Отмена " в приложение, скачивающее веб-сайт. Если вы не хотите скачать или создать пример, вы можете просмотреть окончательный продукт в разделе "Полные примеры" в конце этого раздела. Звездочки помечают изменения в коде.

Чтобы создать пример самостоятельно, следуйте инструкциям в разделе "Скачивание примера", но выберите StarterCode в качестве проекта StartUp вместо CancelATask.

Затем добавьте следующие изменения в файл 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

    • Создайте экземпляр 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
      
  4. В AccessTheWebAsync используйте перегрузку метода HttpClient.GetAsync(String, CancellationToken) типа GetAsync, чтобы скачать содержимое веб-сайта. Передайте 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
    
  5. Если вы не отменяете программу, она создает следующие выходные данные:

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

    Если нажмите кнопку "Отмена" , прежде чем программа завершит скачивание содержимого, программа создает следующие выходные данные:

    Ready to download.
    Download canceled.
    

Отмена списка задач

Вы можете расширить предыдущий пример, чтобы отменить многие задачи, связав один и тот же CancellationTokenSource экземпляр с каждой задачей. Если вы выберете кнопку "Отмена ", вы отмените все задачи, которые еще не завершены.

Скачивание примера

Вы можете скачать полный проект Windows Presentation Foundation (WPF) из примера Async: настройки вашего приложения и затем выполните следующие действия.

  1. Распакуйте скачанный файл и запустите Visual Studio.

  2. В строке меню выберите "Файл", "Открыть", "Проект или решение".

  3. В диалоговом окне "Открыть проект" откройте папку, содержащую пример кода, который вы распаковали, а затем откройте файл решения (.sln) для AsyncFineTuningVB.

  4. В обозревателе решений откройте контекстное меню для проекта CancelAListOfTasks , а затем выберите "Задать в качестве проекта запуска".

  5. Выберите клавишу F5 для запуска проекта.

    Выберите клавиши CTRL+F5, чтобы запустить проект без отладки.

Если вы не хотите скачать проект, вы можете просмотреть MainWindow.xaml.vb файлы в конце этого раздела.

Создание примера

Чтобы расширить пример самостоятельно, выполните пошаговые инструкции в разделе "Скачивание примера", но выберите CancelATask в качестве проекта StartUp. Добавьте следующие изменения в этот проект. Звездочки помечают изменения в программе.

  1. Добавьте метод для создания списка веб-адресов.

    ' ***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 для обработки каждого веб-адреса в списке.

    ' ***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.

Вы можете скачать проекты из Async Sample: Точно настроить приложение.

Отмена примера задачи

Следующий код представляет собой полный файл 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.

См. также