如何确保Xamarin Device.StartTimer只运行一个实例?

时间:2018-03-28 23:52:06

标签: c# xamarin.forms

我在xamarin表单应用程序中运行的计时器如下所示,按钮单击命令通过_isTimerTaskRunning参数false停止它并启动一个新的计时器。 但我相信我的设计中有一个错误,它不是线程安全的,它启动一个新的计时器而不完成前一个。如何确保此处仅运行1个DeviceTimer?我尝试了Thread.Sleep在开始新的之前等待。它有点工作,但我觉得还不是那么安全。我无法找到任何方法事件来检查在开始新的DeviceTimer之前是否已经运行了DeviceTimer。

 this.CompleteTimerClick = new Command(async () =>
            {
                _isTimerTaskRunning = false;                 
                 var success = await RunTimer();
            }

        public bool _isTimerTaskRunning { get; set; } = false;

 private async Task RunTimer()
        {
     sw = Stopwatch.StartNew();

   TimeSpan totalPause = TimeSpan.FromSeconds(totalSecs);
  _isTimerTaskRunning = true;

            Device.StartTimer(TimeSpan.FromMilliseconds(1000), () =>
                       {
                           if (_isTimerTaskRunning)
                           {
                           ts = totalPause - sw.Elapsed;

                              if (ts.TotalSeconds <= 0)
                               {
                                   Device.BeginInvokeOnMainThread(async () =>
                                   {
                                       await DoSomething();
                                   });

                                   return CompleteTimer();
                               }

                               return true;
                           }
                           else
                           {

                               return CompleteTimer();
                           }
                       });

                       }

          private bool CompleteTimer()
        {

            _isTimerTaskRunning = false;
            sw.Stop();

            return false;
        }

我尝试添加锁定

 private Object thisLock = new Object();
      lock (thisLock)
   {
     Task.Run(async () => await RunTimer());
     }

以及如下所示的计时器,但它似乎没有帮助。

Device.StartTimer(TimeSpan.FromMilliseconds(1000), () =>
            {
                lock (thisLock)
                {
 if (_isTimerTaskRunning)
                           {
                           ts = totalPause - sw.Elapsed;

                              if (ts.TotalSeconds <= 0)
                               {
                                   Device.BeginInvokeOnMainThread(async () =>
                                   {
                                       await DoSomething();
                                   });

                                   return CompleteTimer();
                               }

                               return true;
                           }
                           else
                           {

                               return CompleteTimer();
                           }
                       });

                       }
}

1 个答案:

答案 0 :(得分:0)

返回true; //再次运行,或者返回false停止



    Device.StartTimer (new TimeSpan (0, 0, 60), () =>;
    {
        // do something every 60 seconds
        Device.BeginInvokeOnMainThread (() =>; 
        {
          // interact with UI elements
        });
        return true; // runs again, or false to stop
    });