我的代码有一个相当奇怪的行为。我设计了一个文本块来更新一个数字,该数字表示两个
for
循环的进度百分比。
50% 的进度由
IProgress
报告器从一个循环报告,然后剩余的 50% 使用相同的 IProgress
报告器从第二个循环报告。
循环的代码是这样的:
public List<List<string[]>> PopulateSourceList(Sources refSources, CancellationToken cancellationToken=default, ObservableCollectionEx<ISourceModel> NormalReferenceSourceItems = null, ObservableCollectionEx<ISourceModel> CourtCaseSourceItems = null, IProgress <Interfaces.Model.ProgressReport> sourceUpdateProgressReporting = null)
{
Sources sources = refSources;
int sourcesCount = sources.Count;
for (int s = 1; s <= sourcesCount; s++)
{
if (cancellationToken.IsCancellationRequested)
{
cancellationToken.ThrowIfCancellationRequested();
}
Source source = sources[s];
string cited = source?.Cited == true ? "YES" : "NO";
string title;
string year;
try
{
title = source.Field["Title"];
}
catch (Exception)
{
title = string.Empty;
}
try
{
year = source.Field["Year"];
}
catch (Exception)
{
year = string.Empty;
}
string[] results = new string[] { authorBuilder.ToString(), title, cited, tag, year };
if (caseType.Equals("case"))
{
courtRefSources?.Add(new CourtCaseSourceModel(authorBuilder.ToString(), title, cited, tag, year));
cases.Add(results);
}
else
{
normalRefSources?.Add(new NormalReferenceSourceModel(authorBuilder.ToString(), title, cited, tag, year));
items.Add(results);
}
int percentageP = (int)(Math.Round(s/(double)sourcesCount, 2) * 50);
sourceUpdateProgressReporting.Report(new ProgressReport("SourcesExtraction", percentageP, 100));
}
if(NormalReferenceSourceItems != null)
{
normalRefSources.Sort();
int articlesSourceCount = normalRefSources.Count;
for (int a = 0; a < articlesSourceCount; a++)
{
NormalReferenceSourceItems.Add(normalRefSources[a]);
int cuurentPercentage = 50 + (int)(Math.Round(a / (double)articlesSourceCount, 2) * 50);
sourceUpdateProgressReporting.Report(new ProgressReport("SourcesExtraction", cuurentPercentage, 100));
}
sourceUpdateProgressReporting.Report(new Interfaces.Model.ProgressReport("Done", 100, 100));
}
}
对于
IProgress
记者发送的每份报告,都会调用 EventHandler
。 WPF ViewModel 订阅了该事件,并且绑定到 TextBlock
的 Text
的属性在事件侦听器中更新。报告的前半部分 (50%) 已成功捕获并在视图中更新,但随后就停在那里并且不再更新剩余的 50%。
ViewModel中监听事件的方法在这里:
private void OpenDocumentModel_SourceUpdateProgressChangedEvent(object sender, Interfaces.Helpers.SourceUpdateProgressEventArgs e)
{
if (!ReportProgress) return;
if (!e.ProgressState.Equals("Done"))
{
UpdateProgress = $"{(int)e.Value}%";
}
else
{
UpdateProgress = $"{(int)e.Value}%";
UpdateProgress = string.Empty;
ReportProgress = false;
CenitxVisibility = "Visible";
ProgressBarVisibility = "Collapsed";
}
}
UpdatePrgress
是绑定到 TextBlock 的属性。
根据其
setter
的调查,该属性已成功更新,但当发送最终进度报告时,仅前 50% 反映在 TextBlock
本身上。但再次奇怪的是,将 UpdateProgress
属性设置为 string.empty
的最终调用由 TextBlock 反映,并且 View 最终更新成功。
最后一个调用的进度状态为“Done”,触发方式为:
sourceUpdateProgressReporting.Report(new Interfaces.Model.ProgressReport("Done", 100, 100));
有人知道为什么会发生这种情况吗?
好吧,对我来说这似乎只是因为程序运行“太快”了。
我没有太多细节,所以如果您能告诉我们有多少件商品,将会有所帮助 通常在
Sources
和 NormalReferenceSourceItems
里面
我的理论是你的循环
for (int a = 0; a < articlesSourceCount; a++)
{
NormalReferenceSourceItems.Add(normalRefSources[a]);
int cuurentPercentage = 50 + (int)(Math.Round(a / (double)articlesSourceCount, 2) * 50);
sourceUpdateProgressReporting.Report(new ProgressReport("SourcesExtraction", cuurentPercentage, 100));
}
在您有时间注意文本框中的更改之前完成。 现在,如果您已经尝试过延迟或类似的事情,那么了解一下会很有帮助。 事实上,您能够看到
string.empty
的最终更改,因为它是最后一次,因此是永久性的更改。
这可能都是错误的,但在这种情况下,如果您能够向我们概述在测试运行中传递到方法中的数据的种类/大小,我将不胜感激。