0

我是 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

4

2 回答 2

0

我不了解 VB,所以对我来说很难阅读,但我怀疑GetData是你的onClick处理程序。

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

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

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

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

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

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

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

于 2012-05-29T17:38:10.233 回答
0

几件事情要检查:

  1. 如果您的标签是固定宽度,则可能会剪切文本
  2. 如果您使用的是 UpdatePanel,则需要将其模式设置为 'Conditional' 并Update()在 RespCallback 回调方法中调用它,以便使用最新的标签文本值刷新 UI。
于 2012-05-28T17:03:05.653 回答