如何让程序等待 X 秒并允许 UI 执行?
How to have program wait X seconds and allow UI to execute?
我正在制作一款具有自动播放功能的小游戏,但程序运行速度太快,用户无法看到每个阶段的结果。我正在使用 VS 2017,所以我不能使用异步(至少从我读过的内容来看)。如何让程序等待并允许 UI 更新?
我在 do while 循环中工作。游戏的主要部分执行,更新 UI,然后等待玩家点击按钮(假设自动播放不是 运行),自动播放 运行循环重复,但在 UI 更新后它将等待 X 秒。
使用 Timer
组件代替循环,并将循环体放在计时器的 Elapsed
事件中。
而 VS2017 肯定 支持 async
,但在这种情况下它无济于事......对于用户来说,事情仍然进展得太快。
您可以使用 async/await 来减慢事件处理程序的执行速度,而不必拆分逻辑。这很简单:
async void Button_Click(object sender, RoutedEventArgs e) // wpf event handler
{
...
await Task.Delay(1000); // pause 1 second
...
while (someCondition)
{
...
await Task.Delay(1000);
...
}
}
您可以在 msdn 阅读有关 async
/await
的信息。
如果您使用的是 WPF,则必须研究 animations。与手动更改某些内容(位置、大小)相比,使用它们来确保平滑更改要简单得多。
看起来你有几个选择
1.You可以试下Sleep-(不过可能会挂UI)
int Seconds = 1;
Threading.Thread.Sleep(Seconds * 1000);
2.You可以试试这个代码:
int Seconds = 1;
Private void WaitNSeconds(int seconds)
{
if (seconds < 1) return;
DateTime _desired = DateTime.Now.AddSeconds(seconds);
while (DateTime.Now < _desired) {
System.Windows.Forms.Application.DoEvents();
}
}
3.Try 使用 Async 看看会发生什么
async Task MakeDelay() {
await Task.Delay(5000);
}
private async void btnTaskDelay_Click(object sender, EventArgs e) {
await MakeDelay();
}
用法:DelayFactory.DelayAction(500, new Action(() => { this.RunAction(); }));`
//注意Forms.Timer和Timer()有类似的实现。
//假设您将有一个 DelayFactory Static Class
public static void DelayAction(int millisecond, Action action)
{
var timer = new DispatcherTimer();
timer.Tick += delegate
{
action.Invoke();
timer.Stop();
};
timer.Interval = TimeSpan.FromMilliseconds(millisecond);
timer.Start();
}
使用定时器的等待函数,没有 UI 锁。
public void wait(int milliseconds)
{
System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer();
if (milliseconds == 0 || milliseconds < 0) return;
//Console.WriteLine("start wait timer");
timer1.Interval = milliseconds;
timer1.Enabled = true;
timer1.Start();
timer1.Tick += (s, e) =>
{
timer1.Enabled = false;
timer1.Stop();
//Console.WriteLine("stop wait timer");
};
while (timer1.Enabled)
{
Application.DoEvents();
}
}
用法:
wait(1000); //wait one second
我正在制作一款具有自动播放功能的小游戏,但程序运行速度太快,用户无法看到每个阶段的结果。我正在使用 VS 2017,所以我不能使用异步(至少从我读过的内容来看)。如何让程序等待并允许 UI 更新?
我在 do while 循环中工作。游戏的主要部分执行,更新 UI,然后等待玩家点击按钮(假设自动播放不是 运行),自动播放 运行循环重复,但在 UI 更新后它将等待 X 秒。
使用 Timer
组件代替循环,并将循环体放在计时器的 Elapsed
事件中。
而 VS2017 肯定 支持 async
,但在这种情况下它无济于事......对于用户来说,事情仍然进展得太快。
您可以使用 async/await 来减慢事件处理程序的执行速度,而不必拆分逻辑。这很简单:
async void Button_Click(object sender, RoutedEventArgs e) // wpf event handler
{
...
await Task.Delay(1000); // pause 1 second
...
while (someCondition)
{
...
await Task.Delay(1000);
...
}
}
您可以在 msdn 阅读有关 async
/await
的信息。
如果您使用的是 WPF,则必须研究 animations。与手动更改某些内容(位置、大小)相比,使用它们来确保平滑更改要简单得多。
看起来你有几个选择
1.You可以试下Sleep-(不过可能会挂UI)
int Seconds = 1;
Threading.Thread.Sleep(Seconds * 1000);
2.You可以试试这个代码:
int Seconds = 1;
Private void WaitNSeconds(int seconds)
{
if (seconds < 1) return;
DateTime _desired = DateTime.Now.AddSeconds(seconds);
while (DateTime.Now < _desired) {
System.Windows.Forms.Application.DoEvents();
}
}
3.Try 使用 Async 看看会发生什么
async Task MakeDelay() {
await Task.Delay(5000);
}
private async void btnTaskDelay_Click(object sender, EventArgs e) {
await MakeDelay();
}
用法:DelayFactory.DelayAction(500, new Action(() => { this.RunAction(); }));`
//注意Forms.Timer和Timer()有类似的实现。 //假设您将有一个 DelayFactory Static Class
public static void DelayAction(int millisecond, Action action)
{
var timer = new DispatcherTimer();
timer.Tick += delegate
{
action.Invoke();
timer.Stop();
};
timer.Interval = TimeSpan.FromMilliseconds(millisecond);
timer.Start();
}
使用定时器的等待函数,没有 UI 锁。
public void wait(int milliseconds)
{
System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer();
if (milliseconds == 0 || milliseconds < 0) return;
//Console.WriteLine("start wait timer");
timer1.Interval = milliseconds;
timer1.Enabled = true;
timer1.Start();
timer1.Tick += (s, e) =>
{
timer1.Enabled = false;
timer1.Stop();
//Console.WriteLine("stop wait timer");
};
while (timer1.Enabled)
{
Application.DoEvents();
}
}
用法:
wait(1000); //wait one second