我使用異步HTTP請求發送Web請求,並獲得不阻塞UI的響應。這工作正常,直到我嘗試將響應放置到窗體上的標籤上,在該窗體上我得到一個「跨線程操作無效:從其創建的線程以外的線程訪問的控件」。我意識到從不同線程訪問控件的問題,以及使用委託來解決它的問題。
我懷疑發生了什麼事是web回調代碼正在另一個線程上執行,因此它無法訪問在原始線程上創建的控件,但我想我不完全理解回調如何使用其他線程擺在首位。
我想要的是能夠發出Web請求,與其他業務坐上去,然後得到響應後,當它到達,並且能夠把在控制
Public Sub Test()
SendAsynchRequest("http://google.com")
End Sub
Public Sub SendAsynchRequest(ByVal MyURL As String, Optional ByVal Timeout As Integer = 30)
'send an asynch web request
Dim request As HttpWebRequest
Dim result As IAsyncResult
Dim state As WebRequestState
Dim reqtimeout As Integer
Try
request = CType(WebRequest.Create(MyURL), HttpWebRequest) ' Create the request
request.Proxy = Nothing
state = New WebRequestState(request) ' Create the state object used to access the web request
result = request.BeginGetResponse(New AsyncCallback(AddressOf RequestComplete), state)
reqtimeout = 1000 * Timeout
ThreadPool.RegisterWaitForSingleObject(result.AsyncWaitHandle, New WaitOrTimerCallback(AddressOf TimeoutCallback), state, reqtimeout, True)
Catch ex As Exception
log.Error("Error sending web request: " & ex.Message)
End Try
End Sub
Private Sub TimeoutCallback(ByVal state As Object, ByVal timeOut As Boolean)
'request times out
If (timeOut) Then
' Abort the request
CType(state, WebRequestState).Request.Abort()
Dim orig_url = CType(state, WebRequestState).Request
log.Error("Web request to: " & orig_url.RequestUri.ToString & " timed out")
End If
End Sub
Private Sub RequestComplete(ByVal result As IAsyncResult)
'called when the request completes
Dim request As WebRequest
Dim response As System.IO.Stream
Dim sr As StreamReader
Try
request = DirectCast(result.AsyncState, WebRequestState).Request
response = request.EndGetResponse(result).GetResponseStream
sr = New StreamReader(response)
log.Info("Received Web response: " & sr.ReadToEnd)
'*********************************************************
' THIS LINE CAUSES A CROSS-THREAD ERROR
'*********************************************************
TextBox1.Text = sr.ReadToEnd
Catch ex As Exception
log.Error("Received error code: " & ex.Message)
End Try
End Sub
Private Class WebRequestState
'Stores web request for access during async processing
Public Request As WebRequest
Public Sub New(ByVal newRequest As WebRequest)
Request = newRequest
End Sub
End Class
這是適用於所有異步操作,不僅http請求,和 - 沒錯,你應該已經尋找異常文本前問,真的 – mikalai
我不清楚的是在哪裏以及如何創建新線程。我在詢問之前搜遍了各地。關於跨線程異常有很多線程,但我找不到任何有關異步操作的線程。謝謝。 – Timbo