这是我的第一篇文章,就这样... 我有一个名为Job的类,该类连接到构造函数中数据库中的多个表,并从每个表中获取一个项目。正在通过SOAP Web服务访问该数据库。通过单击按钮创建对象。在main中创建类时,将传入搜索字符串和带有文本的自定义进度栏GUI元素。
进度条是一个自定义用户控件,并具有Update()方法来更新消息文本和进度。
我尝试了多种方法来从构造函数中获取GUI(进度条)进行更新,并发现本文(How to use WPF Background Worker)非常有帮助,但是GUI仅在整个方法完成后才进行更新
我尝试从Job类的构造函数中删除方法,并从主线程调用它们,并在两次方法调用之间更新GUI,我尝试使用分派器更新GUI,甚至将它们作为任务等待。我还尝试过直接更新自定义控件的值。尽管如此,GUI似乎只是在搜索方法完成后才更新。
是否有更好的方法来解决此问题?我在Job类的构造函数中做得太多吗?即使在创建对象之前,GUI似乎也没有更新。
private async void AddMasterJob_Click(object sender, RoutedEventArgs e)
{
SearchMethod();
}
//Search method is used in multiple places.
private async void SearchMethod()
{
//This does not change the GUI until the whole method is complete.
await Task.Run(() => CurrentProgressControl.Visibility = Visibility.Visible);
await Task.Run(() => CurrentProgressControl.BringIntoView());
//Checks if record exists during constructor
var tempJob = new Job(SearchBox.Text, CurrentProgressControl);
//Only assign _masterJob if search was successful.
if (tempJob.MasterJob != null)
{
//Try updating the GUI fields directly
await Task.Run(() => CurrentProgressControl.progressBar.Value = 25);
await Task.Run(() => CurrentProgressControl.label.Content = "Getting SubJobs");
//Gets the subjobs and creates an array of subjob objects
tempJob.GetSubJobs();
//Try updating using the update method built into the custom control
CurrentProgressControl.Update("Getting Planning Lines and Ledger Entries.", 45);
//Get the planning lines and ledger entries
tempJob.GetPlanningLinesandLedgerEntries();
CurrentProgressControl.Update("Creating the Estimate Line List.", 60);
//Combines Subjobs, Planning Lines, and Ledger Entries
//Calls CalculateTable(_tableLines)
tempJob.CreateEstimateLineList();
CurrentProgressControl.Update("Separating into Labor and Material.", 75);
//Populate _laborLines and _materialLines
tempJob.SeparateTableLines(tempJob.TableLines);
CurrentProgressControl.Update("Creating SubTotals.", 85);
//Insert the subtotal Lines
tempJob.CreateSubtotalLines(tempJob.LaborLines);
tempJob.CreateSubtotalLines(tempJob.MaterialLines);
CurrentProgressControl.Update("Calculating Totals.", 95);
//Calculate the total estimate column and subtotal lines
tempJob.CalculateTable(tempJob.MaterialLines);
tempJob.CalculateTable(tempJob.LaborLines);
//Calculate the totals for the whole Job
tempJob.CalculateTotals();
CurrentProgressControl.Update("Completed Successfully.", 100);
_masterJob = tempJob;
RaisePropertyChanged("MasterJob");
}
}
GUI将在searchMethod完成之后更新,但不是在此之前更新。搜索方法内部的某些构造方法需要花费几秒钟的时间,因此我希望GUI可以更新多次,而只能完成一次更新,即完成。
答案 0 :(得分:0)
请勿通过Task.Run
更新UI,而应使用它来执行并等待长时间运行的操作:
private async void AddMasterJob_Click(object sender, RoutedEventArgs e)
{
await SearchMethod();
}
private async Task SearchMethod()
{
CurrentProgressControl.Visibility = Visibility.Visible;
CurrentProgressControl.BringIntoView();
var tempJob = new Job(SearchBox.Text, CurrentProgressControl);
if (tempJob.MasterJob != null)
{
CurrentProgressControl.progressBar.Value = 25;
CurrentProgressControl.label.Content = "Getting SubJobs";
await Task.Run(() => tempJob.GetSubJobs());
CurrentProgressControl.Update("Getting Planning Lines and Ledger Entries.", 45);
await Task.Run(() => tempJob.GetPlanningLinesandLedgerEntries());
CurrentProgressControl.Update("Creating the Estimate Line List.", 60);
await Task.Run(() => tempJob.CreateEstimateLineList());
CurrentProgressControl.Update("Separating into Labor and Material.", 75);
await Task.Run(() => tempJob.SeparateTableLines(tempJob.TableLines));
CurrentProgressControl.Update("Creating SubTotals.", 85);
await Task.Run(() =>
{
tempJob.CreateSubtotalLines(tempJob.LaborLines);
tempJob.CreateSubtotalLines(tempJob.MaterialLines);
});
CurrentProgressControl.Update("Calculating Totals.", 95);
await Task.Run(() =>
{
tempJob.CalculateTable(tempJob.MaterialLines);
tempJob.CalculateTable(tempJob.LaborLines);
tempJob.CalculateTotals();
});
CurrentProgressControl.Update("Completed Successfully.", 100);
_masterJob = tempJob;
RaisePropertyChanged("MasterJob");
}
}
或者使用一个Task.Run调用并通过其Dispatcher更新UI:
private async Task SearchMethod()
{
CurrentProgressControl.Visibility = Visibility.Visible;
CurrentProgressControl.BringIntoView();
var tempJob = new Job(SearchBox.Text, CurrentProgressControl);
if (tempJob.MasterJob != null)
{
CurrentProgressControl.progressBar.Value = 25;
CurrentProgressControl.label.Content = "Getting SubJobs";
await Task.Run(() =>
{
tempJob.GetSubJobs());
Dispatcher.Invoke(() => CurrentProgressControl.Update("Getting Planning Lines and Ledger Entries.", 45));
tempJob.GetPlanningLinesandLedgerEntries();
Dispatcher.Invoke(() => CurrentProgressControl.Update("Creating the Estimate Line List.", 60));
tempJob.CreateEstimateLineList();
Dispatcher.Invoke(() => CurrentProgressControl.Update("Separating into Labor and Material.", 75));
tempJob.SeparateTableLines(tempJob.TableLines);
Dispatcher.Invoke(() => CurrentProgressControl.Update("Creating SubTotals.", 85));
tempJob.CreateSubtotalLines(tempJob.LaborLines);
tempJob.CreateSubtotalLines(tempJob.MaterialLines);
Dispatcher.Invoke(() => CurrentProgressControl.Update("Calculating Totals.", 95));
tempJob.CalculateTable(tempJob.MaterialLines);
tempJob.CalculateTable(tempJob.LaborLines);
tempJob.CalculateTotals();
});
CurrentProgressControl.Update("Completed Successfully.", 100);
_masterJob = tempJob;
RaisePropertyChanged("MasterJob");
}
}
如果可能,使作业方法异步:
private async Task SearchMethod()
{
CurrentProgressControl.Visibility = Visibility.Visible;
CurrentProgressControl.BringIntoView();
var tempJob = new Job(SearchBox.Text, CurrentProgressControl);
if (tempJob.MasterJob != null)
{
CurrentProgressControl.progressBar.Value = 25;
CurrentProgressControl.label.Content = "Getting SubJobs";
await tempJob.GetSubJobsAsync();
CurrentProgressControl.Update("Getting Planning Lines and Ledger Entries.", 45);
await tempJob.GetPlanningLinesandLedgerEntriesAsync();
CurrentProgressControl.Update("Creating the Estimate Line List.", 60);
await tempJob.CreateEstimateLineListAsync();
CurrentProgressControl.Update("Separating into Labor and Material.", 75);
await tempJob.SeparateTableLinesAsync(tempJob.TableLines);
CurrentProgressControl.Update("Creating SubTotals.", 85);
await tempJob.ob.CreateSubtotalLinesAsync(tempJob.LaborLines);
await tempJob.CreateSubtotalLinesAsync(tempJob.MaterialLines);
CurrentProgressControl.Update("Calculating Totals.", 95);
await tempJob.CalculateTableAsync(tempJob.MaterialLines);
await tempJob.CalculateTableAsync(tempJob.LaborLines);
await tempJob.CalculateTotalsAsync();
CurrentProgressControl.Update("Completed Successfully.", 100);
_masterJob = tempJob;
RaisePropertyChanged("MasterJob");
}
}