'System.Threading.Tasks.Task(Of String)' 类型的值无法转换为 'String'。在 VB.Net

Value of type 'System.Threading.Tasks.Task(Of String)' cannot be converted to 'String'. in VB.Net

我正在尝试异步调用,但在拆箱结果时遇到问题。这是我得到的错误信息:Value of type 'System.Threading.Tasks.Task(Of String)' cannot be converted to 'String'. 有人可以帮助实现这一目标。这是我使用的代码:

Private Sub Download_Click(sender As Object, e As EventArgs) Handles Button1.Click
    'GET DOWNLOAD URL
    Dim download_url As String = Download_HttpClient(space_id, file_id)

    'ACCESS URL THROUGH GOOGLE CHROME
    Dim proc As New ProcessStartInfo()
    proc.FileName = "C:\Windows\System32\cmd.exe"
    proc.Arguments = "/c start chrome " + download_url
    Process.Start(proc)
End Sub

Public Async Function Download_HttpClient(ByVal spaceId As String, fileId As String) As Task(Of String)
    Dim cookieContainer As New CookieContainer
    Dim httpClientHandler As New HttpClientHandler
    httpClientHandler.AllowAutoRedirect = True
    httpClientHandler.UseCookies = True
    httpClientHandler.CookieContainer = cookieContainer
    Dim httpClient As New HttpClient(httpClientHandler)

    'GET LOGIN CREDENTIALS
    Dim login_url As String = host + "/common/Authentication.json"
    Dim login_parameter As String = "?id=" + user_id + "&pw=" + password
    Dim login_response As HttpResponseMessage = Await httpClient.GetAsync(login_url + login_parameter)
    Dim login_contents As String = Await login_response.Content.ReadAsStringAsync()
    'MessageBox.Show(login_contents)

    'GET DOWNLOAD ID
    Dim download_url As String = host + "/contentsmanagement/SingleContentsDownloadApi.json"
    Dim download_param As String = "?fileId=" + file_id + "&spaceId=" + space_id + "&type=alive"
    Dim download_response As HttpResponseMessage = Await httpClient.GetAsync(download_url + download_param)
    Dim download_contents As String = Await download_response.Content.ReadAsStringAsync()
    Dim downloadId As String = Nothing
    Dim map As Dictionary(Of String, String)
    map = JsonConvert.DeserializeObject(Of Dictionary(Of String, String))(download_contents)
    map.TryGetValue("id", downloadId)
    'MessageBox.Show(downloadId)
    'set DOWNLOAD URL
    Dim url As String = host + "/contentsmanagement/ContentsDownloadApi.json?id=" + downloadId
    Return url

End Function

当一个函数声明为Async和returns一个Task(Of T)时,你需要在调用它时Await它以获得TTask 生成的对象,即:

Dim download_url As String = Download_HttpClient(space_id, file_id)

需要改成这样:

Dim download_url As String = Await Download_HttpClient(space_id, file_id)

您只能在声明为 Async 的方法中使用 Await。这意味着:

Private Sub Download_Click(sender As Object, e As EventArgs) Handles Button1.Click

需要改成这样:

Private Async Sub Download_Click(sender As Object, e As EventArgs) Handles Button1.Click

请注意,您应该只对事件处理程序使用 Async Sub,否则使用 Async Function

我通常会推荐一些关于 Async/Await 的阅读,但这是一个有点高级的主题。作为一般规则,如果您需要调用现有的 Async 函数,例如HttpClient.GetAsync,那么你也需要制作自己的方法Async

如果你有这样的Sub

Private Sub SomeMethod()

你这样称呼它:

SomeMethod()

那会变成这样:

Private Async Function SomeMethodAsync() As Task

还有这个:

Await SomeMethodAsync()

异常是一个事件处理程序,我已经在上面进行了演示。它们必须是 Sub 并且您不能直接调用它们。

同样,如果你有这样的Function

Private Function SomeMethod() As T

你这样称呼它:

Dim result As T = SomeMethod()

那会变成这样:

Private Async Function SomeMethodAsync() As Task(Of T)

还有这个:

Dim result As T = Await SomeMethodAsync()

如果你有一个不是 Async 的方法并且你想在其中调用一个 Async 方法,你必须使你的方法 Async 并使用 Await,然后制作任何调用它的方法 Async 并在其中使用 Await ,并在链上向上直到到达事件处理程序。这就是为什么通常建议,如果你打算使用 Async,你几乎在任何地方都使用它。

如果让一切都变得 Async 太麻烦,那么您可以同步调用异步方法并获取返回的 Task 的结果,例如这个:

Dim download_url As String = Download_HttpClient(space_id, file_id)

变成这样:

Dim download_url_task As Task(Of String) = Download_HttpClient(space_id, file_id)
Dim download_url As String = download_url_task.Result

或仅此:

Dim download_url As String = Download_HttpClient(space_id, file_id).Result