繁体   English   中英

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

[英]How to set up a application-wide Timer?

我想在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分钟运行一次。 如果应用程序“处于活动状态”(在前台),则仅应运行我的解决方案。

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

另外,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方法将不会引发异常。

我不确定您如何安排代码,但是在尝试时:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM