C# 我如何从Device.StartTimer取消?
当我使用System.Threading.Timer时,我可以停止计时器并再次启动:C# 我如何从Device.StartTimer取消?,c#,android,timer,xamarin,C#,Android,Timer,Xamarin,当我使用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.Ti
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并重新启动它的最佳方法是什么?我猜您指的是Xamarin表单中的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;
}
}
}
公共类设备计时器
{
只读操作任务;
只读列表_Tasks=新列表();
只读时间间隔;
公共广播正在进行{get;}
公共bool IsRunning=>\u Tasks.Any(t=>t.IsRunning);
公用设备计时器(操作任务、时间间隔、,
bool isRecurring=false,bool start=false)
{
_任务=任务;
_间隔=间隔;
IsRecurring=IsRecurring;
如果(启动)
Start();
}
公共无效重新启动()
{
停止();
Start();
}
公开作废开始()
{
如果(正在运行)
//已经在运行
返回;
var wrapper=new TaskWrapper(_Task,IsRecurring,true);
_添加(包装器);
Device.StartTimer(_interval,wrapper.RunTask);
}
公共停车场()
{
foreach(var任务在_任务中)
task.IsRunning=false;
_任务。清除();
}
类任务包装器
{
公共bool正在运行{get;set;}
布尔!;
行动任务;
公共任务包装器(操作任务、bool正在执行、bool正在运行)
{
_任务=任务;
_IsRecurring=IsRecurring;
IsRunning=IsRunning;
}
公共bool RunTask()
{
如果(正在运行)
{
_任务();
如果(正在执行)
返回true;
}
//不再需要复发,停下来
返回IsRunning=false;
}
}
}
您可以使用或Thread.Sleep,也可以在构造函数中设置period参数。不,我无法睡眠。应用程序必须工作我在这里面临的问题是,若使用导航到另一个页面,甚至,这个计时器保持打开并继续运行。您的解决方案看起来很有希望,但问题是当用户从页面导航时,应该调用Stop()函数的操作/事件。若我使用OnDisappearing操作,当屏幕被锁定或应用程序被带到后台时,它也会被触发。我不能使用backbutton pressed事件,因为如果按下软件后退按钮,它不会在androd上触发。你觉得怎么样?我用实验结果更新了你的代码。如果您有任何异议,请随时取消编辑。