Often in a Silverlight client you will need to delay the execution of a particular action. There is no intrinsic setTimeout function like in JavaScript window object but you can use System.Windows.Threading.DispatcherTimer object. If you are looking for a tidy wrapper around this object you may want to consider this solution:

public static class UIHelper
{
    public static void SetTimeout(int milliseconds, Action func)
    {
        var timer = new DispatcherTimerContainingAction
                        {
                            Interval = new TimeSpan(0, 0, 0, 0, milliseconds),
                            Action = func
                        };
        timer.Tick += _onTimeout;
        timer.Start();
    }

    private static void _onTimeout(object sender, EventArgs arg)
    {
        var t = sender as DispatcherTimerContainingAction;
        t.Stop();
        t.Action();
        t.Tick -= _onTimeout;
    }
}

public class DispatcherTimerContainingAction : System.Windows.Threading.DispatcherTimer
{
    /// <summary>
    /// uncomment this to see when the DispatcherTimer2 is collected
    /// if you remove  t.Tick -= _onTimeout; line from _onTimeout method
    /// you will see that the timer is never collected
    /// </summary>
    //~DispatcherTimerContainingAction()
    //{
    //    throw new Exception("DispatcherTimerContainingAction is disposed");
    //}

    public Action Action { get; set; }
}

Here is an example of how to use it to show an alert box after two seconds.

UIHelper.SetTimeout(2000, () =>{ 
  // do something here for example show alert box:
  HtmlPage.Window.Alert("2 seconds have passed");
});

As you can see it looks almost like window.setTimeout in JavaScript

Initially I had it without removing the event handler and this way the delegate reference was preventing the garbage collection of the timer. But after a comment from Zi Han (Thanks Zi!) I realized it was not the right way. If you want to be sure that now it is garbage collected you can uncomment the destructor.

Feedback

Posted on 5/13/2008 1:21:16 PM

And you can probably use lambda expression with that?

Posted on 5/13/2008 1:42:55 PM

Yes absolutely, for example

UIHelper.SetTimeout(500, () => HtmlPage.Window.Alert("test"));

Posted on 12/18/2008 3:02:32 AM

Thanks for this piece of code. One question - is there a need to somehow "dispose" of the timer after it has been used.. for memory management purposes?

Posted on 12/18/2008 3:17:55 AM

Thank you Zi, you are right we have to add the removal of the delegate. The code is now updated accordingly

Please post your comments:

Name:  
Email (optional): Your email address will not be posted.
URL (optional):
Comments: HTML will be ignored, URLs will be converted to hyperlinks
Use [code] if(true) alert("OK"); [/code] for source code
 
Enter the text you see in the box: