在异步方法中,任务在创建时启动。 将 Await 运算符应用于方法中特定的点,在此点上任务尚未完成,因而无法继续处理。 通常任务被创建后即等待,如下面的示例所示。
Dim result = Await someWebAccessMethodAsync(url)
但是,如果程序有其他不依赖于任务完成的工作,则可以将创建任务与等待任务分开。
' The following line creates and starts the task.
Dim myTask = someWebAccessMethodAsync(url)
' While the task is running, you can do other work that does not depend
' on the results of the task.
' . . . . .
' The application of Await suspends the rest of this method until the task is
' complete.
Dim result = Await myTask
在启动任务和等待任务之间,可以启动其他任务。 其他任务以并行方式隐式运行,但不会创建其他线程。
以下程序启动三个异步 Web 下载,然后按照调用它们的顺序等待它们。 请注意,运行程序时,任务并不总是按照创建和等待的顺序完成。 任务在创建后开始运行,在此方法到达 await 表达式之前可能已完成一个或多个任务。
注释
若要完成此项目,必须安装 Visual Studio 2012 或更高版本,并且计算机上安装了 .NET Framework 4.5 或更高版本。
有关同时启动多个任务的另一个示例,请参阅如何:使用 Task.WhenAll 扩展异步演练(Visual Basic)。
可以从 开发人员代码示例下载此示例的代码。
设置项目
若要设置 WPF 应用程序,请完成以下步骤。 可以在 演练:使用 Async 和 Await 访问 Web(Visual Basic) 中找到这些步骤的详细说明。
创建包含文本框和按钮的 WPF 应用程序。 为按钮
startButton
命名,并命名文本框resultsTextBox
。添加System.Net.Http的引用。
在MainWindow.xaml.vb文件中,添加一个
Imports
语句用于System.Net.Http
。
添加代码
在设计窗口 MainWindow.xaml 中双击该按钮,以在 MainWindow.xaml.vb 中创建
startButton_Click
事件处理程序。复制以下代码,并将其粘贴到MainWindow.xaml.vb的
startButton_Click
正文中。resultsTextBox.Clear() Await CreateMultipleTasksAsync() resultsTextBox.Text &= vbCrLf & "Control returned to button1_Click."
代码调用一个异步方法,
CreateMultipleTasksAsync
该方法驱动应用程序。将以下支持方法添加到项目:
ProcessURLAsync
使用方法 HttpClient 将网站的内容下载为字节数组。 然后,ProcessURLAsync
支持方法显示并返回数组的长度。DisplayResults
显示每个 URL 的字节数组中的字节数。 此显示显示每个任务完成下载的时间。
复制以下方法,并将其粘贴到MainWindow.xaml.vb中的
startButton_Click
事件处理程序之后。Private Async Function ProcessURLAsync(url As String, client As HttpClient) As Task(Of Integer) Dim byteArray = Await client.GetByteArrayAsync(url) DisplayResults(url, byteArray) Return byteArray.Length End Function Private Sub DisplayResults(url As String, content As Byte()) ' Display the length of each website. The string format ' is designed to be used with a monospaced font, such as ' Lucida Console or Global Monospace. Dim bytes = content.Length ' Strip off the "https://". Dim displayURL = url.Replace("https://", "") resultsTextBox.Text &= String.Format(vbCrLf & "{0,-58} {1,8}", displayURL, bytes) End Sub
最后,定义执行以下步骤的方法
CreateMultipleTasksAsync
。该方法声明
HttpClient
对象,这需要你访问 GetByteArrayAsync 中的ProcessURLAsync
方法。该方法创建并启动三个类型 Task<TResult>的任务,其中
TResult
为整数。 每个任务完成后,DisplayResults
显示任务的 URL 和下载内容长度。 由于任务以异步方式运行,因此结果显示的顺序可能与声明结果的顺序不同。此方法等待每个任务完成。 每个
Await
运算符暂停执行CreateMultipleTasksAsync
,直到等待的任务完成。 此运算符还会从每个已完成的任务的ProcessURLAsync
调用中检索返回值。完成任务并检索整数值后,该方法对网站的长度求和并显示结果。
复制以下方法,并将其粘贴到解决方案中。
Private Async Function CreateMultipleTasksAsync() As Task ' Declare an HttpClient object, and increase the buffer size. The ' default buffer size is 65,536. Dim client As HttpClient = New HttpClient() With {.MaxResponseContentBufferSize = 1000000} ' Create and start the tasks. As each task finishes, DisplayResults ' displays its length. Dim download1 As Task(Of Integer) = ProcessURLAsync("https://msdn.microsoft.com", client) Dim download2 As Task(Of Integer) = ProcessURLAsync("https://msdn.microsoft.com/library/hh156528(VS.110).aspx", client) Dim download3 As Task(Of Integer) = ProcessURLAsync("https://msdn.microsoft.com/library/67w7t67f.aspx", client) ' Await each task. Dim length1 As Integer = Await download1 Dim length2 As Integer = Await download2 Dim length3 As Integer = Await download3 Dim total As Integer = length1 + length2 + length3 ' Display the total count for all of the websites. resultsTextBox.Text &= String.Format(vbCrLf & vbCrLf & "Total bytes returned: {0}" & vbCrLf, total) End Function
选择要运行程序的 F5 键,然后选择 “开始 ”按钮。
多次运行程序,验证这三个任务并不总是按相同的顺序完成,并且完成的顺序不一定是创建和等待的顺序。
示例:
以下代码包含完整示例。
' Add the following Imports statements, and add a reference for System.Net.Http.
Imports System.Net.Http
Class MainWindow
Async Sub startButton_Click(sender As Object, e As RoutedEventArgs) Handles startButton.Click
resultsTextBox.Clear()
Await CreateMultipleTasksAsync()
resultsTextBox.Text &= vbCrLf & "Control returned to button1_Click."
End Sub
Private Async Function CreateMultipleTasksAsync() As Task
' Declare an HttpClient object, and increase the buffer size. The
' default buffer size is 65,536.
Dim client As HttpClient =
New HttpClient() With {.MaxResponseContentBufferSize = 1000000}
' Create and start the tasks. As each task finishes, DisplayResults
' displays its length.
Dim download1 As Task(Of Integer) =
ProcessURLAsync("https://msdn.microsoft.com", client)
Dim download2 As Task(Of Integer) =
ProcessURLAsync("https://msdn.microsoft.com/library/hh156528(VS.110).aspx", client)
Dim download3 As Task(Of Integer) =
ProcessURLAsync("https://msdn.microsoft.com/library/67w7t67f.aspx", client)
' Await each task.
Dim length1 As Integer = Await download1
Dim length2 As Integer = Await download2
Dim length3 As Integer = Await download3
Dim total As Integer = length1 + length2 + length3
' Display the total count for all of the websites.
resultsTextBox.Text &= String.Format(vbCrLf & vbCrLf &
"Total bytes returned: {0}" & vbCrLf, total)
End Function
Private Async Function ProcessURLAsync(url As String, client As HttpClient) As Task(Of Integer)
Dim byteArray = Await client.GetByteArrayAsync(url)
DisplayResults(url, byteArray)
Return byteArray.Length
End Function
Private Sub DisplayResults(url As String, content As Byte())
' Display the length of each website. The string format
' is designed to be used with a monospaced font, such as
' Lucida Console or Global Monospace.
Dim bytes = content.Length
' Strip off the "https://".
Dim displayURL = url.Replace("https://", "")
resultsTextBox.Text &= String.Format(vbCrLf & "{0,-58} {1,8}", displayURL, bytes)
End Sub
End Class