新的异步调用,在这种情况下使用回调 . 以下代码有效 .
代码调用了一个非常基本的Web服务,它返回xml . 如果服务返回xml,代码工作正常,msresponse用xml填充,函数“GetWebserviceData”能够通过函数“CreateDT_Implantable_Device”向调用者返回解析的msresponse . 只要返回xml,这就可以毫无障碍地工作 .
如果服务没有返回任何xml,则respcallback中的此行会抛出一个错误:
“Dim resp As HttpWebResponse = _ CType(req.EndGetResponse(ar),HttpWebResponse)”
抛出的错误是“400-bad request)”
似乎如果服务失败,则回调的线程无法正确完成,整个应用程序在此时锁定 . 它返回到名为“GetWebserviceData”的vb.net表单,并且没有任何控件工作:表单被冻结 .
我已经尝试将try tryches放在回调函数中的所有代码(如下所示),“respcallback”和“GetWebserviceData”中的所有代码(不在下面的代码中) . 正如你在“respcallback”中的try catch中看到的,如果出现此错误,我试图结束回调线程并填充msResponse,以便后面的“GetWebserviceData”中的循环得到满足并将结束 . 这是循环 .
Do while msResponse.Length = 0'等待循环
完整的代码如下:任何帮助将不胜感激 . 我正在尝试允许Web服务失败,让代码继续并提出一个消息框说服务失败 . 显然,我的尝试捕获不能像“respcallback”中看到的那样工作;代码只是锁定 .
代码如下 . 任何帮助,将不胜感激:
公共函数GetWebserviceData(psUDI As String)As DataTable FillGS1Delimeters()miUDI = psUDI ' Create the request object. '尝试Dim wreq As HttpWebRequest = _ CType(WebRequest.Create(“https://accessgudid.nlm.nih.gov/api/v1/devices/lookup.xml?udi=”&psUDI),HttpWebRequest)
' Create the state object.
Dim rs As RequestState = New RequestState()
' Put the request into the state so it can be passed around...
rs.Request = wreq
' Issue the async request..
Dim r As IAsyncResult = _
CType(wreq.BeginGetResponse( _
New AsyncCallback(AddressOf RespCallback), rs), IAsyncResult)
' Wait until the ManualResetEvent is set so that the application
' does not exit until after the callback is called.
allDone.WaitOne()
Do While msResponse.Length = 0
'wait
Loop
'Catch ex As Exception
'msResponse = "Error"
'MessageBox.Show("an error")
'End Try
Return CreateDT_Implantable_Device(msResponse)
End Function
私有函数CreateDT_Implantable_Device(wsResponse As String)Dim dtDevice As DataTable = New DataTable()Dim dtPI As DataTable = New DataTable()Dim ds As DataSet = New DataSet
createEmptyDeviceTable(dtDevice)
createEmptyPITable(dtPI)
ds = StoreXMLAsText(msResponse)
dtPI = FillRecord(dtDevice, ds)
Return dtPI
End Function
Shared Sub RespCallback(ar As IAsyncResult)尝试'从异步结果中获取RequestState对象 . Dim rs As RequestState = CType(ar.AsyncState,RequestState)
' Get the HttpWebRequest from RequestState..
Dim req As HttpWebRequest = rs.Request
' Call EndGetResponse, which returns the HttpWebResponse object
' that came from the request issued above.
Dim resp As HttpWebResponse = _
CType(req.EndGetResponse(ar), HttpWebResponse)
' Start reading data from the respons stream.
Dim ResponseStream As Stream = resp.GetResponseStream()
' Store the reponse stream in RequestState to read
' the stream asynchronously.
rs.ResponseStream = ResponseStream
' Pass rs.BufferRead to BeginRead. Read data into rs.BufferRead.
Dim iarRead As IAsyncResult = _
ResponseStream.BeginRead(rs.BufferRead, 0, BUFFER_SIZE, _
New AsyncCallback(AddressOf ReadCallBack), rs)
Catch ex As Exception
msResponse = "Invalid UDI"
MessageBox.Show(ex.Message)
msResponse = "Error"
End Try
End Sub
Shared Sub ReadCallBack(asAsResult As IAsyncResult)'从AsyncResult获取RequestState对象 . Dim rs As RequestState = CType(asyncResult.AsyncState,RequestState)
' Retrieve the ResponseStream that was set in RespCallback.
Dim responseStream As Stream = rs.ResponseStream
' Read rs.BufferRead to verify that it contains data.
Dim read As Integer = responseStream.EndRead(asyncResult)
If read > 0 Then
' Prepare a Char array buffer for converting to Unicode.
Dim charBuffer(1024) As Char
' Convert byte stream to Char array and then String.
' len contains the number of characters converted to Unicode.
Dim len As Integer = _
rs.StreamDecode.GetChars(rs.BufferRead, 0, read, charBuffer, 0)
Dim str As String = New String(charBuffer, 0, len)
' Append the recently read data to the RequestData stringbuilder
' object contained in RequestState.
rs.RequestData.Append( _
Encoding.ASCII.GetString(rs.BufferRead, 0, read))
' Continue reading data until responseStream.EndRead
' returns –1.
Dim ar As IAsyncResult = _
responseStream.BeginRead(rs.BufferRead, 0, BUFFER_SIZE, _
New AsyncCallback(AddressOf ReadCallBack), rs)
Else
If rs.RequestData.Length > 1 Then
' Display data to the console.
Dim strContent As String
strContent = rs.RequestData.ToString()
msResponse = strContent
Console.WriteLine(strContent)
End If
' Close down the response stream.
responseStream.Close()
' Set the ManualResetEvent so the main thread can exit.
allDone.Set()
End If
Return
End Sub
1 回答
以下是您要从MSDN中引用的内容 .
https://msdn.microsoft.com/en-us/library/2e08f6yc(v=vs.110).aspx?cs-save-lang=1&cs-lang=vb#code-snippet-1
似乎使用Async并等待它会更容易......