当我使用System.Threading.Timer时,我可以停止计时器并再次启动它:
protected override void OnScrollChanged(int l, int t, int oldl, int oldt)
{
if (timer == null)
{
System.Threading.TimerCallback tcb = OnScrollFinished;
timer = new System.Threading.Timer(tcb, null, 700, System.Threading.Timeout.Infinite);
}
else
{
timer.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
timer.Change(700, System.Threading.Timeout.Infinite);
}
}
停止Device.StartTimer并重新启动它的最佳方法是什么?
答案 0 :(得分:12)
我猜你在XamarinForms中指的是Device.StartTime。停止或继续重复任务的方法取决于第二个参数返回的内容:
// run task in 2 minutes
Device.StartTimer(TimeSpan.FromMinutes(2), () =>
{
if (needsToRecur)
{
// returning true will fire task again in 2 minutes.
return true;
}
// No longer need to recur. Stops firing task
return false;
});
如果您想暂时停止此计时器,然后在一段时间后重新开机,则必须再次拨打Device.StartTimer
。将它包装到自己的类中会很好,您可以使用私有成员来确定连续任务是否仍在运行。像这样:
public class DeviceTimer
{
readonly Action _Task;
readonly List<TaskWrapper> _Tasks = new List<TaskWrapper>();
readonly TimeSpan _Interval;
public bool IsRecurring { get; }
public bool IsRunning => _Tasks.Any(t => t.IsRunning);
public DeviceTimer(Action task, TimeSpan interval,
bool isRecurring = false, bool start = false)
{
_Task = task;
_interval = interval;
IsRecurring = isRecurring;
if (start)
Start();
}
public void Restart()
{
Stop();
Start();
}
public void Start()
{
if (IsRunning)
// Already Running
return;
var wrapper = new TaskWrapper(_Task, IsRecurring, true);
_Tasks.Add(wrapper);
Device.StartTimer(_interval, wrapper.RunTask);
}
public void Stop()
{
foreach (var task in _Tasks)
task.IsRunning = false;
_Tasks.Clear();
}
class TaskWrapper
{
public bool IsRunning { get; set; }
bool _IsRecurring;
Action _Task;
public TaskWrapper(Action task, bool isRecurring, bool isRunning)
{
_Task = task;
_IsRecurring = isRecurring;
IsRunning = isRunning;
}
public bool RunTask()
{
if (IsRunning)
{
_Task();
if (_IsRecurring)
return true;
}
// No longer need to recur. Stop
return IsRunning = false;
}
}
}