2010-07-18 80 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