代码应在短暂延迟后执行一次
我有这个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();
在显示对话框之前停止计时器:
delayTimer.Elapsed += (object sender, ElapsedEventArgs e) => { delayTimer.Stop(); Console.WriteLine("test"); textInputDialog.Show(); };
你也可能使用了错误的计时器。 不要使用System.Threading.Timer
或System.Timers
因为这涉及multithreading,它不适用于winforms或WPF。 (这可能是你的MessageBox没有显示的原因 – 它在错误的线程上调用)
在WPF中,您应该使用System.Windows.Threading.DispatcherTimer
编辑
在Winforms中,您应该使用System.Windows.Forms.Timer
(请参阅注释)
这是一个没有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
这样的事情对我有用:
private async Task DelayedShow() { await Task.Delay(500); await _loadPop.textInputDialog.Show(); }
记得像这样调用方法:
BeginInvokeOnMainThread(() => DelayedShow());