Есть ли правило, когда использовать родную NSTimer
по сравнению с альтернативами .NET?
- System.Windows.Forms.Timer
- System.Timers.Timer
- System.Threading.Timer
Есть ли правило, когда использовать родную NSTimer
по сравнению с альтернативами .NET?
IMO основное правило заключается в том, что в любое время некоторые типы (или методы) предлагают дублированные функции между .NET и платформой, на которой вы сейчас работаете, вы должны учитывать долгосрочные кросс-платформенные цели для своего приложения и этот конкретный бит код (повторное использование).
Код IOW с использованием NSTimer
будет работать только на iOS и OSX. Использование таймера .NET будет работать на Windows, Android и, конечно же, на iOS и OSX.
Если вы нацелены на переносимость, я бы использовал таймер .NET
(см. ниже), за исключением случаев, когда у вас нет других вариантов (например, аргумент NSTimer
для вызова метода).
Мой любимый таймер все время, к сожалению, не указан в вашем вопросе, это тот, который предлагается классом Task:
await Task.Delay (20);
//do something after the delay
Использование очень простое. Поэтому вместо этого Timer
code:
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 не мертв, он на острове с Элвисом и Джо Дассином), пришло время подумать о том, что наши обратные вызовы злоупотребляют.
Я предлагаю использовать NSTimer.
Xamarin 5.10:
var sampleTimer = NSTimer.CreateRepeatingScheduledTimer (TimeSpan.FromSeconds (5.0), delegate {
//Write Action Here
});
и добавьте строку. Чтобы запустить таймер!
sampleTimer.Fire();
Остановка после использования:
sampleTimer.Invalidate ();
sampleTimer.Dispose ();
sampleTimer = null;
Я согласен с Poupou и Stephane, но я также сказал бы "это зависит". Если вам нужно реализовать таймер в общей или разделяемой части. Альтернативные альтернативы являются лучшими. Поскольку вопрос касается Xamarin.iOS(а не Xamarin.Android или Xamarin.Forms), я хотел бы добавить следующее, не указанное (пока) решение, которое работает для меня, и это очень просто.
NSTimer timer = NSTimer.CreateRepeatingScheduledTimer(TimeSpan.FromSeconds(3), delegate { MyMethod(); });
Он вызывает MyMethod(); каждые 3 секунды.
В некоторых ответах рекомендуется использовать таймеры .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()
работает полностью нормально.
Итак, я бы сказал: