WPF 屏幕冻结使用 Dispatcher BeginInvoke 方法
WPF screen freeze use Dispatcher BeginInvoke methods
我对循环和冻结屏幕的 WPF 使用有疑问。
我的示例代码在这里
private void Btn1_OnClick(object sender, RoutedEventArgs e)
{
ThreadPool.QueueUserWorkItem(
o =>
{
FaturaCount.Dispatcher.InvokeAsync(() =>
{
int a = 0;
for (int i = 0; i < 10000000000; i++)
{
a = a + i;
}
txtCount.Text = a.ToString();
}, DispatcherPriority.Background);
});
}
循环继续时屏幕冻结。
我想让循环在后面工作,并且在完成之前仍然使用屏幕。
为什么会发生这种情况,我该如何解决?
当您 "invoke into a thread" 时,您是在告诉该线程停止它正在做的任何事情并执行您的代码。
因此,您正在启动一个线程,该线程在 UI 线程执行所有工作时会立即阻塞该线程。那不是你的意图。
不要将整个循环放在 Invoke lambda 中,只需调用需要触摸 UI:
的一小部分
ThreadPool.QueueUserWorkItem(
o =>
{
int a = 0;
for (int i = 0; i < 10000000000; i++)
{
a = a + i;
FaturaCount.Dispatcher.Invoke(() =>
{
txtCount.Text = a.ToString();
});
}
});
显然,上面的代码没有做任何有用的事情,如此快速地重复调用 Invoke 也没有多大意义。这将占用 UI 几乎与您的原始版本一样糟糕。现代硬件可以非常非常快地递增整数和迭代循环。这是您的实际代码,还是线程中的循环实际上在做一些更有用的事情,UI 更新之间的间隔更长?如果我正在实现一个线程,它只在 TextBlock 中显示一个递增的整数,我会在 Invoke 之外的循环中放置一个 Thread.Sleep(250) 或其他东西。让 UI 有机会响应用户输入。
或者更好,因为这是 WPF,编写一个视图模型并通过绑定更新 txtCount.Text
,这将为您执行调用。那时您甚至不必考虑调度员。
我对循环和冻结屏幕的 WPF 使用有疑问。 我的示例代码在这里
private void Btn1_OnClick(object sender, RoutedEventArgs e)
{
ThreadPool.QueueUserWorkItem(
o =>
{
FaturaCount.Dispatcher.InvokeAsync(() =>
{
int a = 0;
for (int i = 0; i < 10000000000; i++)
{
a = a + i;
}
txtCount.Text = a.ToString();
}, DispatcherPriority.Background);
});
}
循环继续时屏幕冻结。 我想让循环在后面工作,并且在完成之前仍然使用屏幕。 为什么会发生这种情况,我该如何解决?
当您 "invoke into a thread" 时,您是在告诉该线程停止它正在做的任何事情并执行您的代码。
因此,您正在启动一个线程,该线程在 UI 线程执行所有工作时会立即阻塞该线程。那不是你的意图。
不要将整个循环放在 Invoke lambda 中,只需调用需要触摸 UI:
的一小部分ThreadPool.QueueUserWorkItem(
o =>
{
int a = 0;
for (int i = 0; i < 10000000000; i++)
{
a = a + i;
FaturaCount.Dispatcher.Invoke(() =>
{
txtCount.Text = a.ToString();
});
}
});
显然,上面的代码没有做任何有用的事情,如此快速地重复调用 Invoke 也没有多大意义。这将占用 UI 几乎与您的原始版本一样糟糕。现代硬件可以非常非常快地递增整数和迭代循环。这是您的实际代码,还是线程中的循环实际上在做一些更有用的事情,UI 更新之间的间隔更长?如果我正在实现一个线程,它只在 TextBlock 中显示一个递增的整数,我会在 Invoke 之外的循环中放置一个 Thread.Sleep(250) 或其他东西。让 UI 有机会响应用户输入。
或者更好,因为这是 WPF,编写一个视图模型并通过绑定更新 txtCount.Text
,这将为您执行调用。那时您甚至不必考虑调度员。