WebRequest Async CallBack Code only gets call the first time

十年热恋 提交于 2019-12-13 03:44:55

问题


I am an absolute beginner on ASP.net (VB.) Please pardon me if the question is too obvious for the experienced members.

I tried to make a simple WebRequest in the async mode in case the target URL takes long to provide the data. In my code below, I just want to see if the callback block (RespCallback) is called correctly every time. If all goes well, lblResult should have the string '123' appended to it every time I click the button which calls the 'GetData' sub.

However, the lblResult only shows 123 after the first click. After the subsequent click, the lblResult only gets appended with '12', as if RespCallback is never called. When I tried to debug this in Visual Studio, the execution actually stepped right into the RespCallback part and the lblResult.Text watch actually shows '123123' but the resulting Web page always shows only '12312'

I am sure I am missing something basic here, but I just don't know what. I was even guessing that it has to do with browser cache (hence the result changes for the second time) but I don't know how to fix that either.

Can someone please help? Thanks in advance.

Jim

Dim myWebRequest As WebRequest

Public Shared allDone As New ManualResetEvent(False)
Private Shared BUFFER_SIZE As Integer = 1024

Public Class RequestState
    ' This class stores the state of the request
    Private Shared BUFFER_SIZE As Integer = 1024
    Public requestData As StringBuilder
    Public bufferRead() As Byte
    Public request As WebRequest
    Public response As WebResponse
    Public responseStream As Stream

    Public Sub New()
        bufferRead = New Byte(BUFFER_SIZE) {}
        requestData = New StringBuilder("")
        request = Nothing
        responseStream = Nothing
    End Sub ' New
End Class ' RequestState

Public Sub GetData(Sender As Object, Args As System.EventArgs)
    lblResult.Text += "1"
    myWebRequest = WebRequest.Create(dataURL)

    Dim myRequestState As New RequestState()

    myRequestState.request = myWebRequest

    ' Start the asynchronous request.
    Dim asyncResult As IAsyncResult = CType(myWebRequest.BeginGetResponse(AddressOf RespCallback, myRequestState), IAsyncResult)


    lblResult.Text += "2"
    allDone.WaitOne()

End Sub

Private Sub RespCallback(asynchronousResult As IAsyncResult)
    lblResult.Text += "3"
    allDone.Set()
End Sub


回答1:


I don't know VB so it's hard to read for me but I'm suspecting GetData is your onClick handler.

First thing that is not right is that you have Shared members. Why your reset event is Shared? It makes all requests use the same object. Basically Your code with ManualResetEvent won't work because after first allDone.Set(), your object remains set (as long as web application lives). To get "123" every time you should add allDone.Reset() after allDone.WaitOne(). In Your situation web request returns to client before RespCallback is called every time except first call (when your reset event is in non-signaled state). AutoResetEvent resets automatically. That's why it worked.

But! You can't do this this way. Making your ResetEvent Shared you make all request use the same object. When more than one request will be processed by your application at the same time you will get undetermined behavior.

Remove Shared from your code. Than your code will work (but not asynchronously) without allDone.Reset() and without AutoResetEvent. But it will provide known results (not depending on amount of requests).

About asynchronous call (now that we have code "working"). Well. There is no async request to your web page. allDone.WaitOne() waits until your async webRequest finish. So basically you could just as well do synchronous request.

You need a special pattern for asynchronous web pages. You can read how to do this here.

But i'm not sure it's what you wanted. Do you want your request to be called asynchronously so that it will not use server resources or do you want to display some message to the user (like "Data is being downloaded...") while your web page will remain fully responsible?

If it's the second one you should use AJAX functionality (Like UpdatePanel or using JavaScript directly). You can read about it here.




回答2:


Couple things to check:

  1. If your label is a fixed width, then it's possible the text is being clipped
  2. If you are using an UpdatePanel, you will need to set its mode to 'Conditional' and call Update() on it in the RespCallback callback method so that the UI gets refreshed with the latest label text value.


来源:https://stackoverflow.com/questions/10787825/webrequest-async-callback-code-only-gets-call-the-first-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!