2012-05-28 29 views
0

我是絕對的初學者在ASP.net(VB。)請原諒我,如果這個問題對於有經驗的會員來說太明顯了。WebRequest異步回調代碼只有第一次打電話

我試圖在異步模式下製作一個簡單的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

聽起來很愚蠢,但也許你的標籤實際上包含'123123',但佈局正在修剪,你只是看不到完整的價值? –

回答

0

我不知道VB所以很難看懂我,但我懷疑GetData是您的onClick處理程序。

首先不對的是你有Shared成員。爲什麼你的重置事件是Shared?它使所有請求使用同一個對象。 基本上你的代碼ManualResetEvent不會工作,因爲在第一個allDone.Set()之後,你的對象保持設置(只要Web應用程序存在)。每次在allDone.WaitOne()之後加入allDone.Reset()即可獲得「123」。 在您的情況下,除第一次呼叫外(當您的重置事件處於非信號狀態時),每次調用RespCallback之前,Web請求都會返回給客戶端。 AutoResetEvent自動重置。這就是它工作的原因。

但是!你不能這樣做。讓你的所有請求都使用同一個對象。當您的應用程序將同時處理多個請求時,您將得到不確定的行爲。

從您的代碼中刪除共享。如果沒有allDone.Reset()而沒有AutoResetEvent,您的代碼將會工作(但不是異步)。但它會提供已知的結果(不取決於請求數量)。

關於異步調用(現在我們有代碼「工作」)。好。沒有異步請求到您的網頁。allDone.WaitOne()一直等到您的異步webRequest完成。所以基本上你可以做同步請求。

您需要異步網頁的特殊模式。你可以閱讀如何做到這一點here

但我不確定這是你想要的。您是否希望異步調用您的請求,以便它不會使用服務器資源,或者您希望向用戶顯示一些消息(如「數據正在被下載...」),而您的網頁將完全負責?

如果是第二個,您應該使用AJAX功能(如UpdatePanel或直接使用JavaScript)。你可以閱讀它here

+0

感謝Grzegorz。我遵循你的建議,現在我每次都得到「123」。我還是有點新本全異步的事情,還是不明白是什麼了WaitOne()會在這種情況下,我怎麼做,如果我不會得到任何異步反正?但在原始問題的範圍內,你已經完全回答了這個問題。我不能投票你的答案,因爲我對董事會太新了。將繼續嘗試。 –

0

幾件事情要檢查:

  1. 如果您的標籤是一個固定的寬度,那麼它是可能的,如果你使用的是文本被截斷
  2. 一個UpdatePanel,你需要將它的模式設置爲'Conditional'並且在RespCallback回調方法上調用Update(),這樣th使用最新的標籤文本值刷新UI。
+0

感謝您的評論,Grzegorz Wilczura和Jeremy。我已檢查過控制器並確保標籤不是固定的寬度。我可以繼續按下按鈕,標籤會多次添加12 12 12(而不是123 123)。 –

+0

另外,我使用ASP:標籤,而不是TextBox或UpdatePanel。我也嘗試將其更改爲TextBox來測試,並得到相同的結果。這些控件嵌套在asp:Content下,但我認爲這不重要。 –

+0

一個觀察是,也許服務器不會等待回調爲瀏覽器提供label.Text值。也許他們在不等待的單獨線程上?我這樣說是因爲我第一次按下按鈕的時候只有一些時候會得到123。我的懷疑是,我得到'123'的時間是Web服務器在瀏覽器提交頁面之前響應速度足夠快的時間(當回調代碼已將label.Text值更改爲'123'時)其他時間,label.Text的值仍然是'12',並且在回調代碼運行之前頁面被獲取。 –

相關問題