可能重复:
修复跨线程异常
我正在使用异步 HTTP 请求来发送 Web 请求并在不阻塞 UI 的情况下获取响应。这工作正常,直到我尝试将响应放入表单上的标签中,此时我得到“跨线程操作无效:从创建它的线程以外的线程访问的控件”。我知道从不同线程访问控件的问题,以及使用委托来解决它的问题。
我怀疑正在发生的事情是 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