【发布时间】:2019-11-22 03:03:54
【问题描述】:
对 Async/Await 不是很熟悉,但是有这个 sn-p 的代码,并且在调用它时仍然会阻塞 UI?我只是得到“等待”光标,无法移动窗口等。
Public Async Function IsPortReachable(ByVal strHost As String, Optional ByVal intPort As Integer = 80, Optional ByVal intTimeoutMs As Integer = 5000) As Task(Of Boolean)
' Throw an exception if no host was passed
If String.IsNullOrEmpty(strHost) Then Throw New ArgumentNullException(NameOf(strHost))
Return Await Task.Run(Function()
Dim clientDone As ManualResetEvent = New ManualResetEvent(False)
Dim bReachable As Boolean = False
Dim hostEntry As DnsEndPoint = New DnsEndPoint(strHost, intPort)
Using socket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
Dim socketEventArg = New SocketAsyncEventArgs With {.RemoteEndPoint = hostEntry}
AddHandler socketEventArg.Completed, Sub(s, e)
bReachable = e.SocketError = SocketError.Success
clientDone.Set()
End Sub
clientDone.Reset()
socket.ConnectAsync(socketEventArg)
clientDone.WaitOne(intTimeoutMs)
Return bReachable
End Using
End Function).ConfigureAwait(False)
End Function
我从这样的主窗体中调用它,这也发生在 Form_Load 上,因此在用户能够“收回控制”程序之前存在不必要的延迟:
Dim bTask As Task(Of Boolean) = IsPortReachable(dicValidated.Item("DNS2Up"), Convert.ToInt32(dicValidated.Item("DNS2UpPort")), 1000)
我的印象是 Async/Await 函数在不同的线程上运行,从而使调用线程(UI 线程)没有阻塞?
【问题讨论】:
-
不要使用
.ConfigureAwaitUI 代码。 -
如果你将你的内部任务函数(使用
Dim clientDone...)移动到它自己的顶级函数,你的代码会更容易阅读。 -
您使用非异步套接字 API 有什么原因吗?
-
异步不创建线程。恰恰相反:它允许多个任务共享一个线程。如果它总是创建线程,那么我们就不需要发明 Async。我们只会使用线程。
标签: multithreading async-await task