WebRequest Async CallBack Code仅在第一次调用时才会被调用

时间:2012-05-28 16:33:13

标签: asp.net vb.net asynchronous webrequest

我是ASP.net的绝对初学者(VB。)如果问题对于有经验的成员来说太明显了,请原谅我。

我试图在异步模式下创建一个简单的WebRequest,以防目标URL花费很长时间来提供数据。在下面的代码中,我只想查看每次是否正确调用回调块(RespCallback)。如果一切顺利,每次单击调用“GetData”子的按钮时,lblResult都应该附加字符串'123'。

然而,lblResult仅在第一次点击后显示123。在随后的单击之后,lblResult只会附加'12',就像从未调用RespCallback一样。当我尝试在Visual Studio中调试它时,执行实际上直接进入RespCallback部分,而lblResult.Text监视实际上显示'123123',但生成的网页始终只显示'12312'

我确信我遗漏了一些基本的东西,但我不知道是什么。我甚至猜测它与浏览器缓存有关(因此结果第二次发生变化),但我不知道如何修复它。

有人可以帮忙吗?提前谢谢。

吉姆

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

2 个答案:

答案 0 :(得分:0)

要检查的事情:

  1. 如果您的标签是固定宽度,那么文本可能会被裁剪
  2. 如果您使用的是UpdatePanel,则需要将其模式设置为“Conditional”并在RespCallback回调方法中调用Update(),以便使用最新的标签文本值刷新UI。

答案 1 :(得分:0)

我不懂VB所以很难为我阅读,但我怀疑GetData是你的onClick处理程序。

不正确的第一件事是你有Shared个成员。为什么您的重置活动是Shared?它使所有请求都使用相同的对象。 基本上,使用ManualResetEvent的代码将无效,因为在第一个allDone.Set()之后,您的对象仍然处于设置状态(只要Web应用程序存在)。每次在allDone.Reset()之后添加allDone.WaitOne()时,要获得“123”。 在您的情况下,除了第一次调用(当您的重置事件处于非信号状态时),每次调用RespCallback之前,Web请求都会返回客户端。 AutoResetEvent会自动重置。这就是它起作用的原因。

但是!你不能这样做。让您ResetEvent Shared使所有请求使用相同的对象。当您的应用程序同时处理多个请求时,您将得到未确定的行为。

从代码中删除Shared。没有allDone.Reset()和没有AutoResetEvent,你的代码将会工作(但不是异步)。但它会提供已知结果(不依赖于请求数量)。

关于异步调用(现在我们有代码“工作”)。好。您的网页没有异步请求。 allDone.WaitOne()等待您的异步webRequest完成。所以基本上你也可以做同步请求。

异步网页需要一种特殊模式。您可以阅读如何执行此操作here

但我不确定这是你想要的。您是否希望异步调用您的请求,以便它不会使用服务器资源,或者您是否希望向用户显示某些消息(例如“正在下载数据...”),而您的网页仍将完全负责?< / p>

如果是第二个,你应该使用AJAX功能(如UpdatePanel或直接使用JavaScript)。你可以阅读它here