我是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
答案 0 :(得分:0)
要检查的事情:
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。