代码应在短暂延迟后执行一次

时间:2015-01-27 10:51:17

标签: c# ios timer xamarin.ios xamarin

我有Timer

Timer delayTimer = new Timer();
delayTimer.Interval = 500;
delayTimer.Elapsed += (object sender, ElapsedEventArgs e) => {
    Console.WriteLine("test");
    textInputDialog.Show();
    delayTimer.Stop();
};
delayTimer.Start();

这里我有以下问题:

  • 计时器永不停止。代码每500ms执行一次。
  • textInputDialog.Show();不起作用(可能导致上述问题)

我的代码出了什么问题?

替代解决方案:

这是Jens Horstmann提到的计时器的替代品。这是在UI线程上调用的:

private async Task SendWithDelay()
{
    await Task.Delay(500);
    textInputDialog.Show();
}

另一种选择是NSTimer

NSTimer.CreateScheduledTimer(new TimeSpan(0,0,0,0,500), delegate {
    textInputDialog.Show();
});

要在UI线程上调用调用,您可以使用InvokeOnMainThread

Timer delayTimer = new Timer();
delayTimer.Interval = 500;
delayTimer.Elapsed += (object sender, ElapsedEventArgs e) => {
    delayTimer.Stop();
    Console.WriteLine("test");
    InvokeOnMainThread (() => {
        textInputDialog.Show();
    });
};
delayTimer.Start();

3 个答案:

答案 0 :(得分:4)

在显示对话框之前停止计时器:

delayTimer.Elapsed += (object sender, ElapsedEventArgs e) => {
    delayTimer.Stop();
    Console.WriteLine("test");
    textInputDialog.Show();
};

你也可能使用了错误的计时器。不要使用System.Threading.TimerSystem.Timers因为这涉及多线程,这对winforms或WPF不起作用。 (这可能是你的MessageBox没有显示的原因 - 它在错误的线程上调用)

在WPF中,您应该使用System.Windows.Threading.DispatcherTimer

修改

在Winforms中,您应该使用System.Windows.Forms.Timer(请参阅注释)

答案 1 :(得分:2)

以下是没有async / await

的解决方案

它恰好符合一个声明,相当优雅 这是一种C#跨平台解决方案,可在延迟后执行操作。 也适用于重复性任务。

using System.Threading;

var delayTimer = new Timer((state) => // Create timer, forget about it
    InvokeOnMainThread(() =>          // Fire on main thread
        textInputDialog.Show()        // Your code goes here
    ),
    null,                             // Ignore the state
    5 * 1000,                         // 5 seconds until the 1st fire
    Timeout.Infinite);                // Do not repeat

答案 2 :(得分:0)

这样的事情对我有用:

    private async Task DelayedShow()
    {
        await Task.Delay(500);
        await _loadPop.textInputDialog.Show();
    }

请记住调用这样的方法:

  BeginInvokeOnMainThread(() => DelayedShow());