gpt4 book ai didi

WPF:如何调用 Dispatcher.BeginInvoke *only* 当队列中没有要调用的内容时?

转载 作者:行者123 更新时间:2023-12-03 13:15:43 25 4
gpt4 key购买 nike

我在 WPF 应用程序中有一个导入文件方法,它读取文件并在数据库中插入一些记录。

此方法在 BackgroundWorker 中运行目的。
我在 Dispatcher.Invoke 中有一个正在更新的进度条称呼。如果我按原样运行,导入 20 万条记录大约需要 1 分钟,如果我没有显示任何进度,则只需 4 到 5 秒!如果我使用 Dispatcher.BeginInvokeBackground优先级,同样需要 4 到 5 秒,但进度条 + 计数器正在更新,大约需要 1 分钟。所以,很明显,用户界面是这里的问题。

另一个问题是我需要显示一个进度,所以我在想是否有任何方法可以使用 Dispatcher.BeginInvoke但首先检查队列中是否有任何内容,如果有,我就跳过它,其行为类似于:第一秒完成 1%,2 秒后完成 50%,第四秒完成 100%)。

对此有什么帮助吗?

谢谢!!!

最佳答案

问题是您的回调在 Dispatcher 上排队。每一个都会导致屏幕重新绘制,并且由于它们处于后台优先级,下一个将等待重新绘制完成后再进行处理,因此每次回调都必须重新绘制一次,这可能会很慢。

与其尝试等到调度程序队列中没有任何内容,不如等到前一个进度回调处理完毕后再发布一个新的。这将确保您一次不会有超过一个事件,因此他们不能排队。

您可以通过在发布回调时设置一个标志并在处理后将其清除来做到这一点。例如:

private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
var pending = false;
for (int i = 0; i < 1000000; i++)
{
// Do some work here
// ...
// Only report progress if there is no progress report pending
if (!pending)
{
// Set a flag so we don't post another progress report until
// this one completes, and then post a new progress report
pending = true;
var currentProgress = i;
Dispatcher.BeginInvoke(new Action(() =>
{
// Do something with currentProgress
progressBar.Value = currentProgress;
// Clear the flag so that the BackgroundWorker
// thread will post another progress report
pending = false;
}), DispatcherPriority.Background);
}
}
}

关于WPF:如何调用 Dispatcher.BeginInvoke *only* 当队列中没有要调用的内容时?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4465600/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com