Megosztás a következőn keresztül:


Több aszinkron feladat indítása és feldolgozása, amint befejeződnek (Visual Basic)

A használatával Task.WhenAnyegyszerre több tevékenységet is elindíthat, és egyenként feldolgozhatja őket a befejezésükkor, ahelyett, hogy a kezdési sorrendben dolgozzák fel őket.

Az alábbi példa egy lekérdezés használatával hoz létre feladatgyűjteményt. Minden feladat letölti egy adott webhely tartalmát. Egy while ciklus minden iterációjában a WhenAny-hez tartozó várakozó hívás visszaadja a feladatot a feladatok gyűjteményéből, amelyik elsőként fejezi be a letöltést. A feladat eltávolításra kerül a gyűjteményből, és feldolgozásra kerül. A ciklus addig ismétlődik, amíg a gyűjtemény nem tartalmaz több feladatot.

Megjegyzés:

A példák futtatásához telepítve kell lennie a Visual Studio 2012-nek vagy újabbnak, valamint a .NET-keretrendszer 4.5-ös vagy újabb verziójának.

A példa letöltése

Töltse le a teljes Windows Presentation Foundation (WPF) projektet az Async-mintából: Az alkalmazás finomhangolása , majd kövesse az alábbi lépéseket.

  1. Bontsa ki a letöltött fájlt, majd indítsa el a Visual Studiót.

  2. A menüsávon válassza a Fájl, Megnyitás, Projekt/Megoldás lehetőséget.

  3. A Projekt megnyitása párbeszédpanelen nyissa meg a kibontott mintakódot tartalmazó mappát, majd nyissa meg az AsyncFineTuningVB megoldásfájlját (.sln).

  4. A Megoldáskezelőben nyissa meg a ProcessTasksAsTheyFinish projekt helyi menüjét, majd válassza a Beállítás kezdőprojektként lehetőséget.

  5. A projekt futtatásához válassza az F5 billentyűt.

    A Ctrl+F5 billentyűkombinációval hibakeresés nélkül futtathatja a projektet.

  6. Futtassa többször a projektet annak ellenőrzéséhez, hogy a letöltött hosszok nem mindig ugyanabban a sorrendben jelennek-e meg.

Ha nem szeretné letölteni a projektet, a témakör végén áttekintheti a MainWindow.xaml.vb fájlt.

A példa létrehozása

Ez a példa kiegészítése annak a kódnak, amely a Cancel Remaining Async Tasks after One Is Complete (Visual Basic) című részben lett kifejlesztve, és ugyanazt a felhasználói felületet használja.

Ha saját maga szeretné létrehozni a példát, kövesse a "Példa letöltése" szakaszban található utasításokat, de startUp projektként válassza a CancelAfterOneTask lehetőséget. Adja hozzá a jelen témakör módosításait a AccessTheWebAsync projekt metódusához. A módosítások csillagokkal vannak megjelölve.

A CancelAfterOneTask projekt már tartalmaz egy lekérdezést, amely végrehajtásakor feladatgyűjteményt hoz létre. Az alábbi kódban minden ProcessURLAsync hívás egy Task<TResult> értéket ad vissza, ahol a TResult egy egész szám.

Dim downloadTasksQuery As IEnumerable(Of Task(Of Integer)) =  
    From url In urlList Select ProcessURLAsync(url, client, ct)  

A projekt MainWindow.xaml.vb fájljában végezze el a következő módosításokat a AccessTheWebAsync metóduson.

  • Hajtsa végre a lekérdezést a Enumerable.ToList alkalmazásával a ToArray helyett.

    Dim downloadTasks As List(Of Task(Of Integer)) = downloadTasksQuery.ToList()  
    
  • Adjon hozzá egy while ciklust, amely végrehajtja a következő lépéseket a gyűjtemény minden feladathoz.

    1. Vár egy hívásra a WhenAny-hez, amely azonosítja a gyűjtemény első feladatát, amely befejezi a letöltést.

      Dim finishedTask As Task(Of Integer) = Await Task.WhenAny(downloadTasks)  
      
    2. Eltávolítja a feladatot a gyűjteményből.

      downloadTasks.Remove(finishedTask)  
      
    3. Várakozik a finishedTask, amelyet egy ProcessURLAsync hívás ad vissza. A finishedTask változó olyan Task<TResult>, ahol a TReturn egy egész szám. A feladat már befejeződött, de még vársz arra, hogy lekérd a letöltött webhely hosszát, ahogy az alábbi példa mutatja.

      Dim length = Await finishedTask  
      resultsTextBox.Text &= String.Format(vbCrLf & "Length of the downloaded website:  {0}" & vbCrLf, length)  
      

A projektet többször is futtatnia kell annak ellenőrzéséhez, hogy a letöltött hosszok nem mindig ugyanabban a sorrendben jelennek-e meg.

Figyelmeztetés

A példában ismertetett ciklusban olyan problémák megoldására használhatja WhenAny , amelyek kis számú feladatot foglalnak magukban. Más megközelítések azonban hatékonyabbak, ha sok feladatot kell feldolgoznia. További információkért és példákért tekintse meg a A feladatok feldolgozása, amikor azok befejeződnek.

Teljes példa

Az alábbi kód a példához tartozó MainWindow.xaml.vb fájl teljes szövege. Csillag jelöli a példához hozzáadott elemeket.

Figyelje meg, hogy hozzá kell adnia egy hivatkozást a következőhöz System.Net.Http: .

A projektet az Async-mintából töltheti le: Az alkalmazás finomhangolása.

' 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 & "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  
  
    ' 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()  
  
        ' ***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 ToList to execute the query and start the download tasks.
        Dim downloadTasks As List(Of Task(Of Integer)) = downloadTasksQuery.ToList()  
  
        ' ***Add a loop to process the tasks one at a time until none remain.  
        While downloadTasks.Count > 0  
            ' ***Identify the first task that completes.  
            Dim finishedTask As Task(Of Integer) = Await Task.WhenAny(downloadTasks)  
  
            ' ***Remove the selected task from the list so that you don't  
            ' process it more than once.  
            downloadTasks.Remove(finishedTask)  
  
            ' ***Await the first completed task and display the results.  
            Dim length = Await finishedTask  
            resultsTextBox.Text &= String.Format(vbCrLf & "Length of the downloaded website:  {0}" & vbCrLf, length)  
        End While  
  
    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 download:  226093  
' Length of the download:  412588  
' Length of the download:  175490  
' Length of the download:  204890  
' Length of the download:  158855  
' Length of the download:  145790  
' Length of the download:  44908  
' Downloads complete.  

Lásd még