Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
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.
Bontsa ki a letöltött fájlt, majd indítsa el a Visual Studiót.
A menüsávon válassza a Fájl, Megnyitás, Projekt/Megoldás lehetőséget.
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).
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.
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.
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.
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)Eltávolítja a feladatot a gyűjteményből.
downloadTasks.Remove(finishedTask)Várakozik a
finishedTask, amelyet egyProcessURLAsynchívás ad vissza. AfinishedTaskváltozó olyan Task<TResult>, ahol aTReturnegy 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.