我有这个类在一段时间内运行函数:
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.xaml
和MainPage.xaml
。出于测试目的,我在MainPage
构造函数中添加了以下代码:
public MainPage()
{
InitializeComponent();
At.Do(delegate { Debug.WriteLine("MainPage"); }, 5000);
}
我的问题如下:如果应用程序首先打开MainPage
,那么计时器工作正常并且委托执行。但是,如果应用程序首先打开Login
然后导航到MainPage
,那么计时器就会无声地失败。为什么会发生这种情况?如何解决?
答案 0 :(得分: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,那么你的计时器也是如此,但是你可以通过将计时器的范围改为适合你想要运行的动作来解决这个问题。