NSTimer
何时使用本机与 .NET 替代方案是否有规则?
- System.Windows.Forms.Timer
- System.Timers.Timer
- System.Threading.Timer
NSTimer
何时使用本机与 .NET 替代方案是否有规则?
如果您的目标是可移植性,我会使用.NET
计时器(见下文),除非您没有其他选择(例如NSTimer
方法调用的参数)。
不幸的是,我一直最喜欢的计时器没有在您的问题中列出,是 Task 类提供的计时器:
await Task.Delay (20);
//do something after the delay
用法很简单。所以代替这段Timer
代码:
void f() {
var timer = new Timer(2000);
timer.Elapsed += OnTimerElapsed;
timer.Start ();
Console.WriteLine ("Timer started, control is back here");
}
void OnTimerElasped (object o, EventArgs e)
{
Console.WriteLine ("tick");
}
你可以使用这个:
void f() {
StartTimer ();
Console.WriteLine ("Timer started, control is back here");
}
async void StartTimer ()
{
while (true) {
await Task.Delay (2000);
Console.WriteLine ("tick");
}
}
或者如果你想要一次执行:
async void StartTimer ()
{
await Task.Delay (2000);
Console.WriteLine ("tick");
}
这是一个真正的好处,因为您无需将计时器保留为实例变量即可.Stop()
。
我发现这种形式更精简。就像我们几年前驳回了 goto 声明(GOTO 并没有死。它与 Elvis 和 Joe Dassin 在岛上)一样,是时候考虑一下我们的回调过度使用了。
我建议使用 NSTimer。
Xamarin 5.10:
var sampleTimer = NSTimer.CreateRepeatingScheduledTimer (TimeSpan.FromSeconds (5.0), delegate {
//Write Action Here
});
并添加一行来启动计时器!
sampleTimer.Fire();
使用后停止:
sampleTimer.Invalidate ();
sampleTimer.Dispose ();
sampleTimer = null;
IMO 的主要规则是,任何时候某些类型(或方法)在 .NET 和您当前正在使用的平台之间提供重复的功能,您必须考虑您的应用程序的长期跨平台目标和特定的代码位(重用)。
使用的 IOW 代码NSTimer
仅适用于 iOS 和 OSX。使用 .NET 计时器将适用于 Windows、Android,当然还有 iOS 和 OSX。
一些答案建议使用 .net 计时器来实现跨平台目标。但问题是Timer
该类在某些 PCL 配置文件中不可用(至少 Xamarin 使用的配置文件)。在这些情况下,解决方法涉及Task.Delay()
按照@stephane-delcroix 的建议使用。我什至为此创建了一个PclTimer
实用程序类。
但...
我发现Task.Delay()
在 iOS 上无法正常工作的情况。如果您尝试在后台任务中使用它:
var taskId = UIApplication.SharedApplication.BeginBackgroundTask(() => {});
// run your timer logic here with Task.Delay()
您会发现间隔已损坏(延迟),与您设置的间隔无关Task.Delay(interval)
。
在那种情况下,NSTimer.CreateRepeatingScheduledTimer()
工作得很好。
所以我想说:
我同意 Poupou 和 Stephane 的观点,但我也会说“这取决于”。如果您需要在公共或共享部分中实现计时器,.Net 替代方案是最好的。由于问题是关于 Xamarin.iOS(不是 Xamarin.Android 或 Xamarin.Forms)我想添加以下未列出的(到目前为止)对我有用的解决方案,它非常简单。
NSTimer timer = NSTimer.CreateRepeatingScheduledTimer(TimeSpan.FromSeconds(3), delegate { MyMethod(); });
它调用 MyMethod(); 每 3 秒。