如何从另一个类中运行的另一个线程更新UI我目前正在编写我的第一个关于C#的程序,我对该语言非常陌生(迄今为止只用于C)。我做了很多研究,但所有的答案都太笼统了,我根本无法解决问题。所以这里是我(非常常见)的问题:我有一个WPF应用程序,它从用户填充的几个文本框中获取输入,然后使用它来对它们进行大量计算。它们应该花费大约2-3分钟,所以我想更新进度条和文本块,告诉我当前的状态。此外,我需要存储用户的UI输入并将它们提供给线程,所以我有第三个类,我用它来创建一个对象,并希望将此对象传递给后台线程。显然我会在另一个线程中运行计算,因此UI不会冻结,但我不知道如何更新UI,因为所有计算方法都是另一个类的一部分。经过大量的研究后,我认为最好的方法是使用调度员和TPL,而不是背景工作者,这里有一个非常简单的程序结构:public partial class MainWindow : Window{
public MainWindow()
{
Initialize Component();
}
private void startCalc(object sender, RoutedEventArgs e)
{
inputValues input = new inputValues();
calcClass calculations = new calcClass();
try
{
input.pota = Convert.ToDouble(aVar.Text);
input.potb = Convert.ToDouble(bVar.Text);
input.potc = Convert.ToDouble(cVar.Text);
input.potd = Convert.ToDouble(dVar.Text);
input.potf = Convert.ToDouble(fVar.Text);
input.potA = Convert.ToDouble(AVar.Text);
input.potB = Convert.ToDouble(BVar.Text);
input.initStart = Convert.ToDouble(initStart.Text);
input.initEnd = Convert.ToDouble(initEnd.Text);
input.inita = Convert.ToDouble(inita.Text);
input.initb = Convert.ToDouble(initb.Text);
input.initc = Convert.ToDouble(initb.Text);
}
catch
{
MessageBox.Show("Some input values are not of the expected Type.", "Wrong Input", MessageBoxButton.OK, MessageBoxImage.Error);
}
Thread calcthread = new Thread(new ParameterizedThreadStart(calculations.testMethod);
calcthread.Start(input);
}public class inputValues{
public double pota, potb, potc, potd, potf, potA, potB;
public double initStart, initEnd, inita, initb, initc;}public class calcClass{如果有人简单解释如何从testmethod内部更新UI,我将非常感激。由于我是C#和面向对象编程的新手,我很可能不会理解太复杂的答案,但我会尽我所能。此外,如果某人有更好的想法(可能使用背景工作者或其他任何东西),我很乐意看到它。
3 回答
森栏
TA贡献1810条经验 获得超5个赞
你应该使用Dispatcher
更新UI线程上的控件,并且正确地说,长时间运行的进程不应该在UI线程上运行。即使您在UI线程上异步运行长时间运行的进程,它仍然可能导致性能问题。
应该注意的是,Dispatcher.CurrentDispatcher
它将返回当前线程的调度程序,而不一定是UI线程。我认为你可以使用它Application.Current.Dispatcher
来获取对UI线程的调度程序的引用,如果你可以使用它,但如果没有,你将不得不将UI调度程序传递给你的后台线程。
通常我使用任务并行库进行线程操作而不是BackgroundWorker
。我发现它更容易使用。
例如,
Task.Factory.StartNew(() => SomeObject.RunLongProcess(someDataObject));
哪里
void RunLongProcess(SomeViewModel someDataObject){ for (int i = 0; i <= 1000; i++) { Thread.Sleep(10); // Update every 10 executions if (i % 10 == 0) { // Send message to UI thread Application.Current.Dispatcher.BeginInvoke( DispatcherPriority.Normal, (Action)(() => someDataObject.ProgressValue = (i / 1000))); } }}
- 3 回答
- 0 关注
- 299 浏览
添加回答
举报
0/150
提交
取消