如何设置应用程序范围的计时器?

时间:2014-06-03 10:04:03

标签: c# windows-phone-8

我想在我的Windows Phone 8应用程序中安装一个计时器,这个计时/运行独立于当前显示的页面。 它应该连接到服务器 - 如果可能的话,在独立的UI任务/线程中 - 并将数据存储在全局对象/列表中。

当前显示页面的独立性是我的观点。

我尝试在App.xaml.cs中跟进:

public partial class App : Application
{
    // creating timer instance
    DispatcherTimer gAppTimer = new DispatcherTimer();
    // timer interval specified as 1 minute
    gAppTimer.Interval = TimeSpan.FromSeconds(60);
    // Sub-routine OnTimerTick that will be called at specified intervall
    gAppTimer.Tick += OnTimerTick;
    // starting the timer
    gAppTimer.Start();
    public void OnTimerTick(Object sender, EventArgs args)
    {
        // text box property is set to current system date.
        // ToString() converts the datetime value into text
        MessageBox.Show("TIMER fired");
    }
    :
    :

但这不起作用。比我尝试在App.xaml.cs中声明对象:

public partial class App : Application
{
    // creating timer instance
    DispatcherTimer gAppTimer = new DispatcherTimer();
    public void OnTimerTick(Object sender, EventArgs args)
    {
        // text box property is set to current system date.
        // ToString() converts the datetime value into text
        MessageBox.Show("TIMER fired");
    }
    :
    :

在我的startpage.xaml.cs:

    // timer interval specified as 1 minute
    App.gAppTimer.Interval = TimeSpan.FromSeconds(60);
    // Sub-routine OnTimerTick that will be called at specified intervall
    App.gAppTimer.Tick += OnTimerTick;
    // starting the timer
    App.gAppTimer.Start();

但这也行不通。

任何想法如何处理我的问题?我不想使用的是后台任务,因为它每30分钟运行一次。如果应用程序处于“活动”状态(在前台),我的解决方案应该只运行。

2 个答案:

答案 0 :(得分:2)

通常使用静态或单例类完成。两者都是全球性的,您可以从每个页面访问它们。

此外,DispatcherTimer在UI线程上调用它的TimerTick方法。如果您不需要在UI线程中,则应使用System.Threading.Timer,它在后台线程中调用方法。

以下是一个例子:

public static class SomeManager {
    private static Timer gAppTimer;
    private static object lockObject = new object();

    public static void StartTimer() {
        if (gAppTimer == null) {
            lock (lockObject) {
                if (gAppTimer == null) {
                    gAppTimer = new Timer(OnTimerTick, null, 60 * 1000, 60 * 1000);
                }
            }
        }
    }

    public static void StopTimer() {
        if (gAppTimer != null) {
            lock (lockObject) {
                if (gAppTimer != null) {
                    gAppTimer.Change(Timeout.Infinite, Timeout.Infinite);
                    gAppTimer = null;
                }
            }
        }
    }

    private static void OnTimerTick(object state) {
        Action();
    }

    public static void Action() {
        // Do what you need to do
    }
}

只需从您的第一页或App.xaml.cs中调用SomeManager.StartTimer(),即可启动计时器。

<强>更新

我稍微更新了代码:

  • Initialize方法重命名为StartTimer

  • 添加了停止计时器的StopTimer方法。然后,您可以致电SomeManager.StartTimer再次启动它。

  • 添加了Action方法,这是实际工作的方法。您可以随时随地调用它。

    注意:计时器将在后台线程中调用此方法,您应该使用Task.Run(() => SomeManager.Action());

  • 之类的方法执行相同操作
  • 添加了一个锁,以确保如果同时从多个线程调用,则Start / Stop方法不会抛出异常。

答案 1 :(得分:0)

我不确定您是如何安排代码的,但是我已经尝试过:

public partial class App : Application
{
    public static PhoneApplicationFrame RootFrame { get; private set; }
    public DispatcherTimer gAppTimer = new DispatcherTimer();
    public void OnTimerTick(Object sender, EventArgs args)
    {
        MessageBox.Show("TIMER fired");
    }

    public App()
    {
        gAppTimer.Interval = TimeSpan.FromSeconds(2);
        // Sub-routine OnTimerTick that will be called at specified intervall
        gAppTimer.Tick += OnTimerTick;
        // starting the timer
        gAppTimer.Start();
        // rest of the code

以上代码有效。 MessageBox每2秒显示一次,如果您已将DispatcherTimer宣布为公开,那么您将能够像这样访问它:

(App.Current as App).gAppTimer.Stop();

另请注意,根据您要实现的目标,您还可以使用System.Threading.Timer

另一方面,您也可以考虑在某处使用public static DispatcherTimer