2010-07-18 73 views
3

在使用Ajax計時器控件時,我一直在嘗試寫入頁面類的實例成員。低於該Ajax TimerControl和實例變量?

我已經建立了一個非常簡單的原始的例子模仿我有確切的問題...

下面的代碼執行一個名爲「UPDATETEXT」每一秒都使用定時器控制方法。每次調用該方法時,都會將計數器變量加1,以說明定時器控件進行回調的次數。

當然,爲了將計數器的值讀取到網頁上,標籤位於更新面板內,且觸發器與定時器相關聯。

標記:

<form id="form1" runat="server"> 
<div> 

    <asp:ScriptManager ID="ScriptManager1" runat="server"> 
    </asp:ScriptManager> 

    <asp:Timer ID="Timer1" runat="server" Interval="1000" OnTick="UpdateText"> 
    </asp:Timer> 

    <asp:UpdatePanel ID="UpdatePanel1" runat="server"> 
    <ContentTemplate> 
     <asp:Label runat="server" Text="" ID="lblCounter"></asp:Label> 
    </ContentTemplate> 

    <Triggers> 
    <asp:AsyncPostBackTrigger ControlID="Timer1" /> 
    </Triggers> 
    </asp:UpdatePanel> 

</div> 
</form> 

代碼隱藏:

public partial class TimerControl : System.Web.UI.Page 
{ 
    private static int loopCounter = 0; 


    protected void Page_Load(object sender, EventArgs e) 
    { 
    } 

    public void UpdateText(object sender, EventArgs e) 
    { 
     lblCounter.Text = loopCounter.ToString(); 
     loopCounter++; 
    } 

} 

如果你運行這個,你會發現它的作品,偉大的,但我不希望 '循環計數器' 變量應該是靜態的,因爲這將適用於整個應用程序級別,並且所有用戶都將讀取/寫入相同的變量。

當我嘗試刪除static關鍵字時,loopCounter變量不再更新,它只停留在零......代碼或瀏覽器(JavaScript)中沒有給出錯誤。

我發現了一個使用會話的臨時解決方法,它可以很好地工作並保留在用戶的上下文中,但除非真的必須使用會話,否則我寧願不使用會話。

任何人都可以請解釋爲什麼一個'實例'成員不能被寫入這樣的 ?爲什麼它只適用於 靜態?

回答

2

這種情況發生的原因主要是因爲http是一個無狀態協議。您的問題的具體原因是請求完成後,頁面的實例未保存在內存中。每次向ASP.NET頁面發出請求時,都會創建一個新頁面實例。您可以通過在頁面類中添加一個默認構造函數並在其中放置斷點來輕鬆檢查。

除了使用會話狀態,你也可以使用viewstate來做到這一點。在這種情況下,這可能是更好的解決方案,因爲您使用的數據(您的計數器)不是用戶特定的,而是特定於頁面的。

+0

感謝您的回答。所以我想通過一個按鈕(不包括任何Ajax)進行常規回發時,會生成一個新的「實例」頁面。這將解釋我所看到的行爲。 Viewstate也是一個不錯的選擇,謝謝。 – Dal 2010-07-19 07:31:15

+0

實際上,任何對aspx頁面的請求(Ajax或常規)都是由新頁面實例處理的。 – 2010-07-19 19:21:58