如何让WebClient的DownloadString异步执行?

How to make WebClient's DownloadString perform asynchronously?

我创建了一个简单的 hello world 程序来从 Web 下载数据。

Private Sub cmdSurf_Click(sender As Object, e As EventArgs) Handles cmdSurf.Click
    Dim wb As New System.Net.WebClient

    Dim uri1 = New Uri(TextBox1.Text)
    Dim str = wb.DownloadString(uri1)
    TextBox2.Text = str
End Sub

很简单吧。我使用 WebClient 对象同步下载字符串,然后将结果显示在 TextBox 中。

现在,我想异步执行此操作。
基本上,在我下载 URI 之后我会做其他事情。
然后下载完成后,我在做它应该做的事情

我也是

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    Dim wb As New System.Net.WebClient

    Dim uri1 = New Uri(TextBox1.Text)
    wb.DownloadStringAsync(uri1)
    TextBox2.Text = ""
End Sub

事实证明 DownloadStringAsync(uri1) 是一个 Sub,所以它没有 return 任何东西。
那么,那么,TextBox2 中应该显示什么?我错过了什么?

更新:我意识到我应该使用 DownloadStringAsyncTask()
所以我这样做了:

Private Async Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    Await downloadStringAndAssignText()
    TextBox2.Text = "I am downloading this. This text will change once the download is finished"
End Sub

Private Async Function downloadStringAndAssignText() As Task
    Dim wb As New System.Net.WebClient

    Dim uri1 = New Uri(TextBox1.Text)
    Dim str = Await wb.DownloadStringTaskAsync(uri1)
    TextBox2.Text = str
End Function

这几乎是正确的。
问题是我想正确地做到这一点

TextBox2.Text = "I am downloading this. This text will change once..."

wb.DownloadStringTaskAsync(uri1) 完成之前调用。
我也不想警告。那我到底应该怎么做呢?

您可以在调用下载字符串的异步方法之前设置文本框的文本。当调用 Await DownloadStringAndAssignText() 时,控制将 return 到调用线程(UI 线程),因此设置并显示 TextBox.Text

当异步方法 returns 时,您可以将 returned 字符串值分配给同一个 TextBox。
你的方法应该 return 一个值,它下载的字符串,而不是给不属于这个方法的 UI 元素赋值(它的职责是下载一个字符串):这里的 return 类型设置为 Task(Of String).
可以直接把async方法的return值赋给同一个TextBox.Text属性.

应使用 Using 语句声明 WebClient 对象,以便在方法完成时将其丢弃。

您可以直接 return WebClient.DownloadStringTaskAsync() 的结果,因为此方法 return 是一个字符串,与您的方法的 return 类型相同。

Imports System.Net

Private Async Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    TextBox2.Text = "I am downloading..."
    TextBox2.Text = Await DownloadStringAndAssignText(TextBox1.Text)
End Sub

Private Async Function DownloadStringAndAssignText(url As String) As Task(Of String)
    Using wb As New WebClient()
        Return Await wb.DownloadStringTaskAsync(New Uri(url))
    End Using
End Function