gpt4 book ai didi

c# - 从另一个类更新 Progressbar

转载 作者:行者123 更新时间:2023-12-02 04:41:59 24 4
gpt4 key购买 nike

我正在用 C#/WPF(.Net 框架 4.0)编写一个应用程序。我遇到的一件事是如何在应用程序非常繁忙时更新控件(如果可能)。我想我只是在努力尝试我在网上找到的东西来让它工作(而且在极少数情况下它会工作)。该应用程序有四个类,一个主窗口类、一个 Worker1 类和一个 Worker2 类以及一个静态 ExtensionMethods 类。 Worker2 从 Worker1 调用并完成大部分工作。当它运行时,CPU 为 100%(核心为 100%,系统有四个核心)。 (所有都在同一个命名空间中。)

public static class ExtensionMethods
{
private static Action EmptyDelegate = delegate() { };

public static void Refresh(this UIElement uiElement)
{

uiElement.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Render, EmptyDelegate);
}
}

主窗口调用 Worker1 中的顶层函数,它经过一些设置然后开始漫长的过程,它是这样的:

MainWindow mainWindow = App.Current.MainWindow as MainWindow;
mainWindow.dispatcher_UpdateProgressBarMaximum(maxValue);
int count=0;
Worker2 worker2 = new Worker2();
while (bytesRead =(readData() !=0) {
count++;
worker2.doWork();
mainWindow.dispatcher_UpdateProgressBar(count);

}

在mainWindow类中是:

dispatcher_UpdateProgressBar(int Value)
{
Dispatcher.BeginInvoke(new Action(() => myProgressBar.Value = value), null);
myProgressBar.Refresh();
}

(我也尝试过:myProgressBar.Dispatcher.Begin...等等

但两者都不重要。对于有 2 或 3 次读取的小文件,我可以看到进度条正在更新。但是对于大文件,直到最后才更新。这也发生在我显示一些状态信息的一些标签控件上。整个工作完成后,我可以选择显示一个消息框,说明已完成的工作。对于标签,当我显示消息框时,标签会更新。该应用程序可以一个接一个地处理许多文件。

我考虑过使用后台线程,但不确定该怎么做。也就是说,worker2.doWork() 部分非常密集,但如果它在它自己的线程上,mainWindow.dispatcher_Update...将在线程开始后立即被调用,并且没有什么可以阻止下一次读取的发生,对吧?

也许按照我的编码方式是不可能的。如果我使用 Backgroundworker,该类会在主窗口或 Worker1 中实例化吗?即使是一两个指针也会很棒。

最佳答案

在 .NET 4.5 中,他们添加了 IProgress<T> 接口(interface)和 Progress<T> 允许您从另一个线程报告进度的类,如果 Progress 它将自动在 UI 线程上运行回调在那里创建了对象。

因为您使用的是 .NET 4.0,所以您并非完全不走运,Microsoft 将这些类发布为 Out of band update通过 NuGet 包到框架 Microsoft.BCL它将这两个类反向移植到 .NET 4.0。

一旦你有Progress<T>它相当易于使用。

void StartWorker()
{
var progress = new Progress<int>(UpdateProgressBar);

worker1.Start(progress)
}


void UpdateProgressBar(int Value)
{
//This code is invoked on the UI thread
myProgressBar.Value = value;
}

//Elsewhere in Worker1
void Start(IProgress<int> progress)
{

int count=0;
Worker2 worker2 = new Worker2();
while (bytesRead =(readData() !=0)
{
count++;
worker2.doWork();
progress.Report(count);
}
}

然而,尽管如此,您还是应该尝试重新考虑您的数据模型。 “拥抱 WPF”并开始使用像 MVVM 这样的概念设置绑定(bind)并更新数据对象,然后更新您的 UI(并且您可以将所有 UI 编码代码放入 ViewModel 的 OnPropertyChanged 事件中)。

关于c# - 从另一个类更新 Progressbar,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20643569/

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