Biri Tamamlandıktan Sonra Kalan Zaman Uyumsuz Görevleri İptal Etme (Visual Basic)

yöntemini ile birlikte kullanarak Task.WhenAny , bir CancellationTokengörev tamamlandığında kalan tüm görevleri iptal edebilirsiniz. yöntemi, WhenAny bir görev koleksiyonu olan bir bağımsız değişken alır. yöntemi tüm görevleri başlatır ve tek bir görev döndürür. Koleksiyondaki herhangi bir görev tamamlandığında tek görev tamamlanır.

Bu örnekte, bir iptal belirtecinin görev koleksiyonundan tamamlanıp kalan görevleri iptal etmek üzere ilk görevi tutmak için birlikte WhenAny nasıl kullanılacağı gösterilmektedir. Her görev bir web sitesinin içeriğini indirir. Örnek, tamamlanmak üzere ilk indirmenin içeriğinin uzunluğunu görüntüler ve diğer indirmeleri iptal eder.

Not

Örnekleri çalıştırmak için bilgisayarınızda Visual Studio 2012 veya üzeri ve .NET Framework 4.5 veya daha yeni bir sürümü yüklü olmalıdır.

Örneği İndirme

Windows Presentation Foundation (WPF) projesinin tamamını Async Sample: Fine Tuning Your Application adresinden indirebilir ve ardından aşağıdaki adımları izleyebilirsiniz.

  1. İndirdiğiniz dosyanın sıkıştırmasını açın ve Visual Studio'yu başlatın.

  2. Menü çubuğunda Dosya, Aç, Proje/Çözüm'e tıklayın.

  3. Projeyi Aç iletişim kutusunda, sıkıştırmasını kaldırdığınız örnek kodun bulunduğu klasörü açın ve ardından AsyncFineTuningVB için çözüm (.sln) dosyasını açın.

  4. Çözüm Gezgini'de CancelAfterOneTask projesinin kısayol menüsünü açın ve ardından StartUp Projesi Olarak Ayarla'yı seçin.

  5. Projeyi çalıştırmak için F5 anahtarını seçin.

    Projeyi hata ayıklamadan çalıştırmak için Ctrl+F5 tuşlarını seçin.

  6. Önce farklı indirmelerin tamamlandığını doğrulamak için programı birkaç kez çalıştırın.

Projeyi indirmek istemiyorsanız, bu konunun sonundaki MainWindow.xaml.vb dosyasını gözden geçirebilirsiniz.

Örneği Oluşturma

Bu konudaki örnek, bir görev listesini iptal etmek için Zaman Uyumsuz Görevi İptal Et veya Görev Listesi'nde geliştirilen projeye eklenir. İptal düğmesi açıkça kullanılmasa da örnek aynı kullanıcı arabirimini kullanır.

Örneği kendiniz oluşturmak için, adım adım "Örneği İndirme" bölümündeki yönergeleri izleyin, ancak StartUp Projesi olarak CancelAListOfTasks'i seçin. Bu konudaki değişiklikleri bu projeye ekleyin.

CancelAListOfTasks projesinin MainWindow.xaml.vb dosyasında, her web sitesi için işleme adımlarını döngüden AccessTheWebAsync aşağıdaki zaman uyumsuz yönteme taşıyarak geçişi başlatın.

' ***Bundle the processing steps for a website into one async method.
Async Function ProcessURLAsync(url As String, client As HttpClient, ct As CancellationToken) As Task(Of Integer)

    ' GetAsync returns a Task(Of HttpResponseMessage).
    Dim response As HttpResponseMessage = Await client.GetAsync(url, ct)

    ' Retrieve the website contents from the HttpResponseMessage.
    Dim urlContents As Byte() = Await response.Content.ReadAsByteArrayAsync()

    Return urlContents.Length
End Function

bu AccessTheWebAsyncörnekte, bir dizi görev oluşturup başlatmak için bir sorgu ToArray , yöntemi ve WhenAny yöntemi kullanılır. dizisine uygulaması WhenAny , beklendiğinde görev dizisinde tamamlanmaya ulaşmak için ilk görevi değerlendiren tek bir görev döndürür.

içinde AccessTheWebAsyncaşağıdaki değişiklikleri yapın. Yıldız işaretleri, kod dosyasındaki değişiklikleri işaretler.

  1. Döngüye açıklama ekleyin veya döngünün silinmesini sağlayın.

  2. Yürütülürken genel görevlerden oluşan bir koleksiyon oluşturan bir sorgu oluşturun. çağrısının ProcessURLAsync her biri bir Task<TResult> where TResult değerini tamsayı olarak döndürür.

    ' ***Create a query that, when executed, returns a collection of tasks.
    Dim downloadTasksQuery As IEnumerable(Of Task(Of Integer)) =
        From url In urlList Select ProcessURLAsync(url, client, ct)
    
  3. Sorguyu yürütmek ve görevleri başlatmak için çağrısı ToArray yapın. Sonraki adımda yönteminin WhenAny uygulanması sorguyu yürütür ve kullanmadan ToArraygörevleri başlatır, ancak diğer yöntemler çalışmayabilir. En güvenli yöntem, sorgunun açıkça yürütülmesini zorlamaktır.

    ' ***Use ToArray to execute the query and start the download tasks.
    Dim downloadTasks As Task(Of Integer)() = downloadTasksQuery.ToArray()
    
  4. Görev koleksiyonunda çağrısı WhenAny yapın. WhenAny veya Task(Of Task(Of Integer))Task<Task<int>>döndürür. Başka bir ifadeyle, WhenAny tek Task(Of Integer) bir görevi veya Task<int> ne zaman beklediğini değerlendiren bir görev döndürür. Bu tek görev koleksiyonda bitirecek ilk görevdir. İlk tamamlanan görev öğesine finishedTaskatanır. türü, TResultTask<TResult> değerinin finishedTask dönüş türü ProcessURLAsyncolduğundan tamsayıdır.

    ' ***Call WhenAny and then await the result. The task that finishes
    ' first is assigned to finishedTask.
    Dim finishedTask As Task(Of Integer) = Await Task.WhenAny(downloadTasks)
    
  5. Bu örnekte yalnızca ilk olarak biten görevle ilgileniyorsunuz. Bu nedenle, kalan görevleri iptal etmek için kullanın CancellationTokenSource.Cancel .

    ' ***Cancel the rest of the downloads. You just want the first one.
    cts.Cancel()
    
  6. Son olarak, indirilen içeriğin uzunluğunu almayı bekleyin finishedTask .

    Dim length = Await finishedTask
    resultsTextBox.Text &= vbCrLf & $"Length of the downloaded website:  {length}" & vbCrLf
    

Önce farklı indirmelerin tamamlandığını doğrulamak için programı birkaç kez çalıştırın.

Tam Örnek

Aşağıdaki kod, örneğin tam MainWindow.xaml.vb veya MainWindow.xaml.cs dosyasıdır. Yıldız işaretleri, bu örnek için eklenen öğeleri işaretler.

için System.Net.Httpbir başvuru eklemeniz gerektiğine dikkat edin.

Projeyi Zaman Uyumsuz Örnek: Uygulamanızda İnce Ayarlama'dan indirebilirsiniz.

' 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
            Await AccessTheWebAsync(cts.Token)
            resultsTextBox.Text &= vbCrLf & "Download complete."

        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

    ' You can still include a Cancel button if you want to.
    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()

        '' Comment out or delete the loop.
        ''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

        ' ***Create a query that, when executed, returns a collection of tasks.
        Dim downloadTasksQuery As IEnumerable(Of Task(Of Integer)) =
            From url In urlList Select ProcessURLAsync(url, client, ct)

        ' ***Use ToArray to execute the query and start the download tasks.
        Dim downloadTasks As Task(Of Integer)() = downloadTasksQuery.ToArray()

        ' ***Call WhenAny and then await the result. The task that finishes
        ' first is assigned to finishedTask.
        Dim finishedTask As Task(Of Integer) = Await Task.WhenAny(downloadTasks)

        ' ***Cancel the rest of the downloads. You just want the first one.
        cts.Cancel()

        ' ***Await the first completed task and display the results
        ' Run the program several times to demonstrate that different
        ' websites can finish first.
        Dim length = Await finishedTask
        resultsTextBox.Text &= vbCrLf & $"Length of the downloaded website:  {length}" & vbCrLf
    End Function

    ' ***Bundle the processing steps for a website into one async method.
    Async Function ProcessURLAsync(url As String, client As HttpClient, ct As CancellationToken) As Task(Of Integer)

        ' GetAsync returns a Task(Of HttpResponseMessage).
        Dim response As HttpResponseMessage = Await client.GetAsync(url, ct)

        ' Retrieve the website contents from the HttpResponseMessage.
        Dim urlContents As Byte() = Await response.Content.ReadAsByteArrayAsync()

        Return urlContents.Length
    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

' Sample output:

' Length of the downloaded website:  158856

' Download complete.

Ayrıca bkz.