代码应在短暂延迟后执行一次
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();
这里我有以下问题:
- 计时器永远不会停止。代码每 500 毫秒执行一次。
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
,因为这涉及多线程,不能很好地与 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
我有这个Timer
:
Timer delayTimer = new Timer();
delayTimer.Interval = 500;
delayTimer.Elapsed += (object sender, ElapsedEventArgs e) => {
Console.WriteLine("test");
textInputDialog.Show();
delayTimer.Stop();
};
delayTimer.Start();
这里我有以下问题:
- 计时器永远不会停止。代码每 500 毫秒执行一次。
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
,因为这涉及多线程,不能很好地与 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