0

我有这个类可以在一段时间内运行函数:

namespace Test
{
    public static class At
    {
        private static void ExecuteDelayedAction(object o)
        {
            (o as Action).Invoke();
        }

        public static void Do(Action action, TimeSpan delay, int interval = Timeout.Infinite)
        {
            new Timer(new TimerCallback(At.ExecuteDelayedAction), action, Convert.ToInt32(delay.TotalMilliseconds), interval);
        }
        public static void Do(Action action, DateTime dueTime, int interval = Timeout.Infinite)
        {
            if (dueTime >= DateTime.Now) Do(action, dueTime - DateTime.Now, interval);
        }
        public static void Do(Action action, int delay, int interval = Timeout.Infinite)
        {
            Do(action, TimeSpan.FromMilliseconds(delay), interval);
        }
    }
}

而且在我的应用程序中,我有两个页面 -Login.xamlMainPage.xaml. 仅出于测试目的,我在MainPage构造函数中放入了以下代码:

public MainPage()
{
    InitializeComponent();
    At.Do(delegate { Debug.WriteLine("MainPage"); }, 5000);
}

我的问题如下:如果应用程序MainPage首先打开,那么计时器工作正常并且委托被执行。但是,如果应用程序Login首先打开然后导航到,MainPage那么计时器就会静默失败。为什么会发生,如何解决?

4

1 回答 1

1

我怀疑您正在创建的计时器正在被垃圾收集(GC'ed),因为您没有在任何地方持有对它的引用,而只是删除了对新创建的计时器的引用。

由于在页面之间导航会导致创建相当多的内存,因此可能会触发 GC。

尝试通过保留对计时器对象的引用来修复它。我会创建一个Do类实例,您可以在其中隐藏一个私有计时器,并保留对它的引用。但是,如果您想保留当前的静态类设计,您可以只返回一个作为计时器的对象。

    public static object Do(Action action, TimeSpan delay, int interval = Timeout.Infinite)
    {
        var t = new Timer(new TimerCallback(At.ExecuteDelayedAction), action, Convert.ToInt32(delay.TotalMilliseconds), interval);
        return t;
    }

然后您需要在页面中存储对计时器的引用。

public MainPage()
{
    InitializeComponent();
    this.doObject = At.Do(delegate { Debug.WriteLine("MainPage"); }, 5000);
}

当然,如果MainPage是 GC,那么您的计时器也会如此,但您可以通过将计时器的范围更改为适合您要运行的操作的范围来解决此问题。

于 2012-12-30T14:39:58.487 回答