2012-10-18 42 views
2

可能重複:
Fixing a Cross-Thread Exception異步HTTP請求導致錯扣例外

我使用異步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 
+0

這是適用於所有異步操作,不僅http請求,和 - 沒錯,你應該已經尋找異常文本前問,真的 – mikalai

+0

我不清楚的是在哪裏以及如何創建新線程。我在詢問之前搜遍了各地。關於跨線程異常有很多線程,但我找不到任何有關異步操作的線程。謝謝。 – Timbo

回答

1

我的回覆我確信這已被回答了很多次。 您需要使用Control.Invoke函數在UI線程上運行更新。

1

在錯誤的行,替換爲以下:

TextBox1.Invoke(Sub() 
        TextBox1.Text = sr.ReadToEnd 
       End Sub)