【问题标题】:PCL .NET 4.5 TimerPCL .NET 4.5 定时器
【发布时间】:2014-01-16 00:25:20
【问题描述】:

我正在使用 Xamarin 和 MvvmCross 构建跨平台应用程序。我需要每分钟调用一次服务器进行更新(稍后我会推送通知),但我无法在我的核心项目中设置计时器。我见过 MvvmCross N+42 但我相信目标项目较旧,允许使用计时器。下面是我的目标框架。

有没有更好的方法让我不断调用调用服务的方法?

  • .NET Framework 4.5 及更高版本
  • Windows 应用商店应用 (Windows 8) 及更高版本
  • Windows Phone 8
  • Xamarin.Android
  • Xamarin.iOS

【问题讨论】:

  • 谢谢,我已经看到了该线程,但由于 Xamarin,我无法针对 Windows 8.1 及更高版本。
  • 是的,但在 8.1 中提到永久修复之前建议了一些解决方法。至少我是这么读的。
  • 我通过创建 .NET 4.0 PCL 并在其中创建计时器实例尝试了一些解决方法,但它们似乎使我调试的应用程序崩溃。我不知道是不是因为我使用的是带有 MVVMCross 的 Xamarin
  • 我犯了一个大错误,我没有引用该项目。是一个严重的错误

标签: c# xamarin .net-4.5 mvvmcross


【解决方案1】:

@stevemorgan 的回答非常有效。 我基于该代码创建了一个 Timer 实用程序,以使其更具可重用性。 我还添加了一个“runOnce”参数,它将在第一次滴答后停止计时器

public class PclTimer
{
    public bool IsRunning { get; private set; }

    public TimeSpan Interval { get; set; }
    public Action Tick { get; set; }
    public bool RunOnce { get; set; }
    public Action Stopped { get; set; }
    public Action Started { get; set; }

    public PclTimer(TimeSpan interval, Action tick = null, bool runOnce = false)
    {
        Interval = interval;
        Tick = tick;
        RunOnce = runOnce;
    }

    public PclTimer Start()
    {
        if (!IsRunning)
        {
            IsRunning = true;
            Started?.Invoke();
            var t = RunTimer();
        }

        return this;
    }

    public void Stop()
    {
        IsRunning = false;
        Stopped?.Invoke();
    }

    private async Task RunTimer()
    {
        while (IsRunning)
        {
            await Task.Delay(Interval);

            if (IsRunning)
            {
                Tick?.Invoke();

                if (RunOnce)
                {
                    Stop();
                }
            }
        }
    }
}

我在 MvvmCross 中使用它没有问题:

timer = new Timer(TimeSpan.FromSeconds(4), 
            () => ShowViewModel<UserMatchViewModel>(), true)
            .Start();

【讨论】:

    【解决方案2】:

    感谢 async/await 的奇妙之处,您始终可以自己做:

    public async Task RunTimer()
    {
        while(_timerRunning)
        {
            // Do Work
            // ...
    
            await Task.Delay(_timerInterval);
        }
    }
    

    当你调用它时,不要等待它。它将在后台线程上运行,您可以通过从其他地方设置 _timerRunning 字段来终止循环(或通过终止调用返回的任务)。

    【讨论】:

      猜你喜欢
      • 2023-03-21
      • 1970-01-01
      • 1970-01-01
      • 2017-02-09
      • 2014-12-04
      • 1970-01-01
      • 1970-01-01
      • 2013-06-28
      • 2015-06-12
      相关资源
      最近更新 更多