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

本文关键字:应用程序 范围 定时器 设置 何设置 | 更新日期: 2023-09-27 18:06:17

我想有一个定时器在我的windows phone 8应用程序,这´s计数/运行独立于当前显示的页面。它应该连接到服务器——如果可能的话,在一个独立于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。example .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分钟才运行一次。我的解决方案应该只运行,如果应用程序是"活动"(前台)。

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

这通常使用静态或单例类来完成。它们都是全局的,你可以从每个页面访问它们。

同样,DispatcherTimer在UI线程上调用它的TimerTick方法。如果你不需要在UI线程中,你应该使用System.Threading。定时器,在后台线程中调用一个方法。

下面是一个例子:

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方法在多个线程同时调用时不会抛出异常。

我不知道你是如何安排你的代码,但正如我所尝试的:

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