c# - 我想每分钟运行一个从我的 OnAppearing() 开始的方法。我需要将其作为任务运行吗?

标签 c# xamarin xamarin.forms timer

这是我想出的代码。它似乎有效,但我担心这可能不是做我想做的事情的好方法。我需要的是在 OnAppearing 发生后每分钟运行一个方法,并在 OnDisappearing() 时停止;

protected async override void OnAppearing()
{
   base.OnAppearing();
   BindingContext = vm;

   cts = new CancellationTokenSource();
   if (Settings.mode == MO.Practice)
   {
      if (!App.stopWatch.IsRunning) { App.stopWatch.Start(); }
            Device.StartTimer(new TimeSpan(0, 0, 5), () =>
      {
          if (App.stopWatch.IsRunning && App.stopWatch.Elapsed.Seconds >= 60)
          {
             // Here's the method I want to run. After it's finished
             // I call BeginInvoke .. to update info on the screen
             if (App.DB.ReducePoints() == true)
                Device.BeginInvokeOnMainThread(() =>
                {
                   vm.PifInfo = GetPifInfo();
                });
                App.stopWatch.Restart();
             }
             return true;
            });
        }
        await GetCards(cts.Token);
    }
}

protected override void OnDisappearing()
{
    Unsubscribe();
    cts.Cancel();
    if (App.stopWatch.IsRunning) { App.stopWatch.Stop(); }
    base.OnDisappearing();
}

不是问题的一部分,但我也欢迎对代码提出任何意见。

最佳答案

您可以通过从 Device.StartTimer 返回正确的值来更简单地完成此操作, 重复 true , 不再重复 false并且不使用 StopWatch . ( source 指出 While the callback returns true, the timer will keep recurring. 正如您从源代码中看到的那样,该方法不需要 Func<Task<bool>> 它只需要 Func<bool> 回调,因此无需使用 Task。)

在类里面

volatile bool run;

在 OnAppearing 中

run = true;
Device.StartTimer(new TimeSpan(0, 1, 0), () => {
if (run) { /*do what you want;*/ return true; }
else { return false; }
});

在消失

run = false;

编辑 - 根据 OP 的要求

这是代码。我将留下我原来的答案来帮助任何需要这个的人。

volatile bool run;

protected async override void OnAppearing()
{
   base.OnAppearing();
   BindingContext = vm;    
   cts = new CancellationTokenSource();
   if (Settings.mode == MO.Practice)
   {
        run = true;
        Device.StartTimer(new TimeSpan(0, 1, 0), () => 
        {
            if (run) 
            { 
                 if (App.DB.ReducePoints() == true)
                    Device.BeginInvokeOnMainThread(() =>
                    {
                       vm.PifInfo = GetPifInfo();
                    });
                 return true; 
            }
            else { return false; }
        });
        await GetCards(cts.Token);
    }
}

protected override void OnDisappearing()
{
    run = false;
    Unsubscribe();
    cts.Cancel();
    base.OnDisappearing();
}

关于c# - 我想每分钟运行一个从我的 OnAppearing() 开始的方法。我需要将其作为任务运行吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54388183/

相关文章:

c# - 查找可用时间段 C#

c# - 通过来自同一对象实例(或基础)的反射调用私有(private)/ protected 方法

c# - 通过 HttpClient 向 Saucelabs 发送 PUT 请求没有响应

ios - 在 iOS 应用程序上使用 xbuild 不会生成 ipa

android - 在多列中显示重复项

c# - 获取无线网络的主机IP

xamarin - 我什么时候应该触发一个事件以使我的 ListView 滚动到底部

android - Android 和 iPhone 之间的 Xamarin 可移植性

c# - Xamarin:样式 TabWidget

keyboard - 如何在 Xamarin Forms 中按下按钮时关闭键盘