在控制台应用程序中按预期工作(我从c# YouTube教程转换而来,原因我不会让你厌烦),但在桌面应用程序中调用GetAsync时没有异常抛出。
Imports System
Imports System.Net.Http
Module Module1
Sub Main()
Dim strContent As Task(Of String) = GetRequest("http://www.google.com.pk")
Console.WriteLine(strContent.Result)
Console.ReadKey()
End Sub
Async Function GetRequest(url As String) As Task(Of String)
Using client As New HttpClient()
Using response As HttpResponseMessage = Await client.GetAsync(url)
Using content As HttpContent = response.Content
Dim myContent As String = Await content.ReadAsStringAsync()
Return myContent
End Using
End Using
End Using
End Function
End Module
可以,但下面的不行。可能是一个新手错误,虽然我不是一个真正的新手-从来没有使用System.Net.Http直到现在,我一直在房子周围与这个。
在调用GetAsync时挂起…
Imports System
Imports System.Net.Http
Public Class HTTP_Test_One
Public Sub HTTP_Test_One_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim strContent As Task(Of String) = GetRequest("http://www.google.com.pk")
txtResults.Text = strContent.Result
End Sub
Async Function GetRequest(url As String) As Task(Of String)
Using client As New HttpClient()
Using response As HttpResponseMessage = Await client.GetAsync(url)
Using content As HttpContent = response.Content
Dim myContent As String = Await content.ReadAsStringAsync()
Return myContent
End Using
End Using
End Using
End Function
End Class
我并不是百分百地相信这一点,我怀疑我可能会被比我更了解情况的人纠正,甚至可能是为什么。在我看来,等待你的任务的结果是堵塞,为什么不是在控制台应用程序,我的猜测是因为它没有UI线程的开销,或被事件触发。只需重新编写按钮事件处理程序,我至少可以得到所需的响应。
Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim strContent As String = Await GetRequest("http://www.google.com.pk")
txtResults.Text = strContent
End Sub
注意我已经改变异步的事件,这意味着我可以等待GetRequest的反应()而不是看任务结果
阻塞UI线程中的异步代码很可能导致死锁。这已经在许多与异步相关的资源中进行了讨论;我的参考书目是Stephen Cleary的系列文章,他在https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html上讨论了这个具体问题,并详细说明了为什么阻塞会导致死锁。
正确的方法是将事件处理程序设置为Async
,然后将Await
作为其中的结果,即
Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim content = Await GetRequest("http://www.google.com.pk")
txtResults.Text = content
End Sub
注意,由于处理错误的问题,通常不建议使用Async Sub
,但事件处理程序是例外——Async Sub
是专门为UI事件处理程序设计的。