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

Code should be executed one time after short delay

我有这个Timer:

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

这里我有以下问题:

我的代码有什么问题?

备选方案:

正如 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();

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

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(见评论)

像这样的东西对我有用:

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

记得这样调用方法:

  BeginInvokeOnMainThread(() => DelayedShow());

这是一个没有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