private void button1_Click(object sender, RoutedEventArgs e)
{
int i = 0;
while (i < 500)
{
label1.Content = i.ToString();
// System.Threading.Thread.Sleep(2000);
++i;
}
}
Run Code Online (Sandbox Code Playgroud)
我试图在每次变量递增时更新Label的内容,但是发生的事情是label1的内容只更改一次,并且仅在while循环终止后才更改.我认为计数器变量的增量是如此之快以至于UI线程无法赶上它,所以我想让线程空闲2秒,希望看到label1更改值500次.它也没用.为什么?
正如其他人所说,问题是你正在阻止UI线程.
Application.DoEvents我建议您使用a DispatcherTimer来安排更新,而不是使用建议.示例代码:
DispatcherTimer timer = new DispatcherTimer();
timer.Tick += delegate
{
label.Content = counter.ToString();
counter++;
if (counter == 500)
{
timer.Stop();
}
};
timer.Interval = TimeSpan.FromMilliseconds(2000);
timer.Start();
Run Code Online (Sandbox Code Playgroud)
(我不确定是否Application.DoEvents可以在WPF中运行,并且它通常被认为是不好的做法.如果它确实有效,我怀疑它可以保证在未来的版本中工作.在同一个应用程序中混合两个UI只是为了这对我来说听起来真是个坏主意.)
您可以使用Timer(System.Threading.Timer或者System.Timers.Timer),但在这两种情况下,您都需要编组回调度程序线程.DispatcherTimer使这更简单 - Tick事件总是在Dispatcher线程内被触发.
编辑:如果你真的想要一个等价的DoEvents,这里的代码我已经验证确实有效,并且基于MSDN文档Dispatcher.PushFrame解释如何Application.DoEvents从WPF中完成相同的操作:
public void DoEvents()
{
DispatcherFrame frame = new DispatcherFrame();
Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,
new DispatcherOperationCallback(ExitFrames), frame);
Dispatcher.PushFrame(frame);
}
public object ExitFrames(object f)
{
((DispatcherFrame)f).Continue = false;
return null;
}
private void ButtonClick(object sender, RoutedEventArgs e)
{
for (int i = 0; i < 500; i++)
{
label.Content = i.ToString();
DoEvents();
}
}
Run Code Online (Sandbox Code Playgroud)
我仍然不会推荐这一点 - WPF(如Windows Forms)是基于事件驱动的工作方式设计的.
| 归档时间: |
|
| 查看次数: |
8660 次 |
| 最近记录: |