Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Xamarin.iOS中的NSTimer与Timer-何时使用什么?_C#_Xamarin.ios_Xamarin - Fatal编程技术网

C# Xamarin.iOS中的NSTimer与Timer-何时使用什么?

C# Xamarin.iOS中的NSTimer与Timer-何时使用什么?,c#,xamarin.ios,xamarin,C#,Xamarin.ios,Xamarin,与.NET替代方案相比,何时使用本机NSTimer是否有规则 System.Windows.Forms.Timer 系统计时器 系统线程计时器 IMO的基本规则是,任何类型(或方法)在.NET和当前正在进行的平台之间提供重复的特征时,必须考虑到您的应用程序的长期跨平台目标和特定的代码位(重用)。 使用NSTimer的IOW代码只在iOS和OSX上工作。使用.NET计时器可以在Windows、Android以及当然还有iOS和OSX上使用。如果您希望实现可移植性,我会使用.NET计时器(见下文

与.NET替代方案相比,何时使用本机
NSTimer
是否有规则

  • System.Windows.Forms.Timer
  • 系统计时器
  • 系统线程计时器

IMO的基本规则是,任何类型(或方法)在.NET和当前正在进行的平台之间提供重复的特征时,必须考虑到您的应用程序的长期跨平台目标和特定的代码位(重用)。


使用
NSTimer
的IOW代码只在iOS和OSX上工作。使用.NET计时器可以在Windows、Android以及当然还有iOS和OSX上使用。

如果您希望实现可移植性,我会使用
.NET
计时器(见下文),除非您没有其他选择(例如方法调用的
NSTimer
参数)

很遗憾,您的问题中没有列出我一直最喜欢的计时器,是任务类提供的计时器:

等待任务延迟(20);
//耽搁之后做点什么
用法很简单。因此,不要使用此
计时器
代码:

void f(){
var定时器=新定时器(2000);
timer.appeased+=ontimerecursed;
timer.Start();
Console.WriteLine(“计时器启动,控件回到这里”);
}
void OnTimerElasped(对象o,事件参数e)
{
Console.WriteLine(“勾号”);
}
您可以使用以下选项:

void f(){
StartTimer();
Console.WriteLine(“计时器启动,控件回到这里”);
}
异步void StartTimer()
{
while(true){
等待任务。延迟(2000);
Console.WriteLine(“勾号”);
}
}
或者,如果您想要一次执行:

async void StartTimer()
{
等待任务。延迟(2000);
Console.WriteLine(“勾号”);
}
这是一个真正的好处,因为您不需要将计时器保持为实例变量,只需要
.Stop()


我觉得这个表格更精简。正如我们几年前驳回了goto的声明(goto没有死。它和Elvis和Joe Dassin在岛上),现在是时候考虑我们的回调过度使用了。

我同意Poupou和Stephane的观点,但我也会说“这要看情况而定”。 如果您需要在公共或共享部分中实现计时器,那么.Net替代方案是最好的。因为问题是关于Xamarin.iOS(不是Xamarin.Android或Xamarin.Forms)的,所以我想添加以下未列出(到目前为止)的解决方案,它非常简单

NSTimer timer = NSTimer.CreateRepeatingScheduledTimer(TimeSpan.FromSeconds(3), delegate { MyMethod(); });

它调用MyMethod();每3秒。

我建议使用NSTimer

Xamarin 5.10:

var sampleTimer = NSTimer.CreateRepeatingScheduledTimer (TimeSpan.FromSeconds (5.0), delegate {

    //Write Action Here
                }); 
    sampleTimer.Invalidate ();
    sampleTimer.Dispose ();
    sampleTimer = null;
并添加一行来启动计时器

sampleTimer.Fire();
使用后停止:

var sampleTimer = NSTimer.CreateRepeatingScheduledTimer (TimeSpan.FromSeconds (5.0), delegate {

    //Write Action Here
                }); 
    sampleTimer.Invalidate ();
    sampleTimer.Dispose ();
    sampleTimer = null;

一些答案建议使用.net计时器实现跨平台目标。但问题是,
Timer
类在某些PCL配置文件中不可用(至少Xamarin使用的配置文件)。在这些情况下,解决方法包括使用@stephane delcroix建议的
Task.Delay()
。我甚至为这个问题创建了一个新的解决方案

但是…

我发现
Task.Delay()
在iOS上无法正常工作。如果您尝试在后台任务中使用它:

var taskId = UIApplication.SharedApplication.BeginBackgroundTask(() => {});
// run your timer logic here with Task.Delay() 
您会发现间隔已损坏(延迟),与您在
Task.Delay(interval)
上设置的间隔不符

在这种情况下,
NSTimer.CreateRepeatingScheduledTimer()
完全可以正常工作

所以我想说:

  • 是否需要在后台任务中运行计时器?=>使用NSTimer
  • 你不需要背景任务吗?=>使用.NET

James关于自动发布池的回答是真的吗?ThreadPool已经有了对
NSAutoreleasePool
的内部支持,并且在5.2中添加了对
Thread
的支持,请参见OTH对
任务的支持和
BackgroundWorker
仍然需要特别支持(重复使用同一个线程需要耗尽池中的水)@poupou+1我确信我不久前读到过这个问题,不确定它是否得到了解决。我已经根据您的文档链接删除了我的答案:)Task.Delay()不是真正的计时器,是吗?我的意思是,我真的不能安排事情。我看到它,并把它当作计时器。它可以安排要执行的代码(放置在等待之后)。它只是更加简化了,不需要委托。然后一个重复计时器将是while(true){wait Task.Delay(20);}?在您的示例中有没有停止计时器的方法?出于兴趣,您选择NSTimer而不是.net计时器的理由是什么?