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

C# 代码应在短延迟后执行一次,c#,ios,timer,xamarin.ios,xamarin,C#,Ios,Timer,Xamarin.ios,Xamarin,我有一个计时器: Timer delayTimer = new Timer(); delayTimer.Interval = 500; delayTimer.Elapsed += (object sender, ElapsedEventArgs e) => { Console.WriteLine("test"); textInputDialog.Show(); delayTimer.Stop(); }; delayTimer.Start(); NSTimer.Cr

我有一个
计时器

Timer delayTimer = new Timer();
delayTimer.Interval = 500;
delayTimer.Elapsed += (object sender, ElapsedEventArgs e) => {
    Console.WriteLine("test");
    textInputDialog.Show();
    delayTimer.Stop();
};
delayTimer.Start();
NSTimer.CreateScheduledTimer(new TimeSpan(0,0,0,0,500), delegate {
    textInputDialog.Show();
});
这里我有以下问题:

  • 计时器从不停止。代码每500毫秒执行一次
  • textInputDialog.Show()不工作(可能是上述问题的原因)
我的代码有什么问题

替代解决方案:

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

private async Task SendWithDelay()
{
    await Task.Delay(500);
    textInputDialog.Show();
}
另一种选择是
NSTimer

Timer delayTimer = new Timer();
delayTimer.Interval = 500;
delayTimer.Elapsed += (object sender, ElapsedEventArgs e) => {
    Console.WriteLine("test");
    textInputDialog.Show();
    delayTimer.Stop();
};
delayTimer.Start();
NSTimer.CreateScheduledTimer(new TimeSpan(0,0,0,0,500), delegate {
    textInputDialog.Show();
});
要调用UI线程上的调用,可以使用:


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

delayTimer.Elapsed += (object sender, ElapsedEventArgs e) => {
    delayTimer.Stop();
    Console.WriteLine("test");
    textInputDialog.Show();
};
另外,您可能使用了错误的计时器。不要使用
System.Threading.Timer
System.Timer
,因为这涉及到多线程处理,这在winforms或WPF中不起作用。(这可能是您的MessageBox没有显示的原因-它在错误的线程上被调用)

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

编辑


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

类似的东西对我很有用:

    private async Task DelayedShow()
    {
        await Task.Delay(500);
        await _loadPop.textInputDialog.Show();
    }
请记住按如下方式调用该方法:

  BeginInvokeOnMainThread(() => DelayedShow());
这是一个不带
async
/
wait
它也恰好适合于一个单独的语句,这是相当优雅的。
这是一个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

什么是文本输入对话框?消息框?A
UIAlertView
。也许我需要一个类变量而不是局部变量。为什么不使用一个具有短延迟的等待方法呢?你想让你的代码延迟运行一次吗?那么我认为这是非常好的,这也是一个选择。我看到经常使用
定时器
,因此我尝试了这种方法。尽管如此,我在代码中犯的错误还是很有趣的。这是真的。因此,textInputDialog.Show();从未被称为?@测试,正如DrKoch所说,系统。计时器涉及多线程处理。而是使用System.Windows.Forms.Timer,它是为Windows窗体工作而专门设计的。现在计时器只调用一次。但第二个问题似乎是,正如您所说,它是在另一个线程上调用的。我不使用
System.Windows.Forms
。相反,我使用
Xamarin.iOS
并添加标记。我不知道这是否会有这么大的不同。唯一的问题是我可以在那里使用哪个计时器,以便在UI线程上调用它。Jens Horstmann的wait方法完成了这项工作。你需要在你的tick事件处理程序中启动/注册一个UI线程的操作(通过dispatcher),google it。