views:

26

answers:

1

Hi

I've been having an issue trying to write to an instance member of my page class when using the Ajax timer control.

I've built a very simple crude example below which emulates the exact problem I'm having...

The code below executes a method called "UpdateText" every second using the timer control. Every time the method is called it increments a counter variable by one to illustrate how many times the timer control has made a callback.

Of course, in order to read the value of the counter onto the web page the label sits inside an update panel with a trigger associated to the timer.

Markup:

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

CodeBehind:

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++;
    }

}

If you run this you'll find it works, great but I don't want the 'loopCounter' variable to be static as this would apply to the whole application level and all users would be reading/writing to the same variable.

When I try to remove the static keyword, the loopCounter variable is no longer updated, it just stays at zero... There are no errors given in the code or in the browser (JavaScript).

I've found a temporary work around by using sessions instead which work nicely and remain in the context of a user but I prefer not to use sessions unless I really have to.

Could anyone please explain why an 'instance' member cannot be written to like this? Why does it only work for static?

+2  A: 

The reason this happens is essentially because http is a stateless protocol. The specific reason for your problem is that instances of pages are not kept in memory after a request has finished. Each time you make a request to an ASP.NET page, a new page instance is created. You can easily check this for yourself by adding a default constructor to your page class and putting a breakpoint there.

Besides using session state, you could also use viewstate for this. In this case that would probably be a better solution, since the data you are using (your counter) is not user-specific but page-specific.

Ronald Wildenberg
@Ronald Wildenberg - Thanks for the answer. So I guess when a regular postback is made via a button (excluding any Ajax) a new 'instance' of the page is generated? This would explain the behaviour I am seeing.Viewstate is also a good choice, thank you.
Dal
Actually, any request (Ajax or regular) to an aspx page is handled by a new page instance.
Ronald Wildenberg