Click here to Skip to main content
Click here to Skip to main content

A Stoppable Timer Control for ASP.NET Atlas

By , 30 Jul 2006
 

Introduction

ASP.NET Atlas has a timer server control which periodically postbacks to the server. However, the TimerControl has a bug that prevents it to be stopped from server side code during partial rendering. Time and again, I encounter the question in Atlas forums which ask for a workaround to this bug. This article is based on my post in Atlas forums, and has detailed explanation on how to solve this problem. Hopefully, the issue will be resolved in a future version of Atlas.

Using the Code

Here are the steps you must take to use this control:

  1. Copy the StoppableTimer.cs file to the App_Code directory of your web site.
  2. Modify the web.config file to add the following element:
    <configuration>
       <system.web>
           <pages>
            <tagMapping>
                <add tagType="Microsoft.Web.UI.Controls.TimerControl" 
                     mappedTagType="VRK.Controls.StoppableTimer,App_Code"/>
            </tagMapping>
    
  3. The configuration setting automatically allows your class to be used instead of the Atlas TimerControl without any changes to existing web pages. In a new page, you can continue to use the control using the following syntax:
    <atlas:TimerControl ID="Timer1" 
          runat="server" Interval="500" OnTick="Timer1_Tick" 
          Enabled="false" />
  4. If the bug is fixed in a future CTP, you can just remove the configuration setting, and everything will work as it is.

How it Works

There are two problems with the Atlas server control which causes this bug:

  1. The control does not generate any ID for the timer.

  2. It does not try to stop the timer in response to postbacks or callbacks.

The timer control presented in the article modifies the rendering of the TimerControl as follows:

protected override void RenderScript(ScriptTextWriter writer)
{
  if (!IsPageInPartialRendering)
  {
    writer.WriteStartElement("timer");
    writer.WriteAttributeString("id", this.UniqueID);
    writer.WriteAttributeString("interval", 
           this.Interval.ToString(CultureInfo.InvariantCulture));
    writer.WriteAttributeString("enabled", this.Enabled.ToString().ToLower());
    writer.WriteStartElement("tick");
    writer.WriteStartElement("postBack");
    writer.WriteAttributeString("target", this.UniqueID);
    writer.WriteAttributeString("eventArgument", string.Empty);
    writer.WriteEndElement();
    writer.WriteEndElement();
    writer.WriteEndElement();
  }
}

As you can see, the control renders the XML-Script except for partial rendering. During partial rendering, the timer object on the client web page is not destroyed, so all that needs to be done is to enable or disable the client-side object. This is done in the OnPreRender method:

protected override void OnPreRender(EventArgs e)
{
   if (IsPageInPartialRendering)
   {
     string scriptSnippetFormat = "$object(\"{0}\").set_enabled({1});";
     string scriptSnippet = 
       String.Format(scriptSnippetFormat, 
       this.UniqueID, 
       this.Enabled.ToString().ToLower());

     Page.ClientScript.RegisterStartupScript(
        GetType(),
        this.UniqueID,
        scriptSnippet,
        true);
    }

    base.OnPreRender(e);
}

The only remaining interesting part of the code is obtaining the instance of the script manager on the page and finding whether the ScriptManager is in partial rendering mode:

bool IsPageInPartialRendering
{
   get
   {
      ScriptManager manager = ScriptManager.GetCurrent(this.Page);
      return (manager != null && manager.IsInPartialRenderingMode);
   }
}

Conclusion

This is a quick fix for a bug that exist in Atlas as I know in June CTP. It may be fixed in the coming releases of Atlas. Fortunately, if you use the fix as described, all you will need to do is to change the configuration setting, and you don't need to change any of the source code of any page.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Rama Krishna Vavilala
Architect
United States United States
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralNot cross-browser compatiblememberXpnctoc30 Sep '08 - 5:21 
I implemented this code in a project and it works great under IE6/7. However, it fails under FireFox 3. Do you have any suggestions for getting this thing to work in FireFox?
Generaltype or namespace not foundmemberblumonde15 Dec '06 - 4:56 
I followed the instructions and when running the site, I receive errors below:
 
Error 1 The type or namespace name 'TimerControl' could not be found (are you missing a using directive or an assembly reference?)
 
Error 2 The type or namespace name 'ScriptTextWriter' could not be found (are you missing a using directive or an assembly reference?)
 
Where did I go wrong? Please help. Thanks.
 
blumonde
 

GeneralRe: type or namespace not foundmemberstatic426 Jan '07 - 8:57 
The code was based on an earlier version of asp.net ajax (atlas)...
 
I'm now trying to figure out if they added this behaviour in asp.net ajax 1.0 RTM so that I can remove this code from my product or apply changes so that it works with the new version.
GeneralRe: type or namespace not foundmembertbenami31 Jul '08 - 6:45 
I still cannot make it work with VS 2008. Can you posted and update code with reference to new AJAX?
 
Thanks
Generalchanging intervalmemberrodrigo.argenta14 Nov '06 - 8:06 
great work!!! You save a lot of my time.
but, i am trying to change the interval property in de code-behind, but does not work. Any idea ?
 
Rodrigo
GeneralIt did not work with me!!memberAL3600B10 Nov '06 - 23:53 
I followed the steps, downloaded timestopper.cs and did put it in App_code.
When i try to update web.config, it gives me an error about unknown element (pages) which was not closed in the article but i closed the tag with no success.
I only need a timer which refresh every some interval.
GeneralGREAT JOB! THANKS A LOT!memberarinpcssouth8 Nov '06 - 7:05 
I spent 4 hours last night and I tried every possible thing you can imagin. This is going to save my project man!!! Thanks.
 
Arin
GeneralYou are a geniusmemberlevalencia8 Nov '06 - 5:46 
It works perfect and I had problems with that.
 
THANK YOU VERY MUCH
GeneralThanks!memberArtem L6 Nov '06 - 2:38 
Actually, I was searching of how to solve this issue and have found this nice solution.
Thx.
GeneralOutstandingmemberbeep29 Oct '06 - 17:43 
Thanks for fixing the interval thing. I had tried everything I could think of.
 
Bruce

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130523.1 | Last Updated 30 Jul 2006
Article Copyright 2006 by Rama Krishna Vavilala
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid