我的代码中有一个相当奇怪的行为。我设计了一个Textblock,用一个数字来表示两个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;
List<NormalReferenceSourceModel> normalRefSources = new List<NormalReferenceSourceModel>();
List<CourtCaseSourceModel> courtRefSources = new List<CourtCaseSourceModel>();
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%)会在View中成功捕获和更新,但随后它会停止在那里,并且永远不会更新剩余的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最终成功更新。
最后一个调用是携带“完成”作为进度状态的调用,由以下各项触发:
sourceUpdateProgressReporting.Report(new Interfaces.Model.ProgressReport("Done", 100, 100));
型
有没有人知道为什么会发生这种情况?
1条答案
按热度按时间xienkqul1#
好吧,对我来说,这似乎只是因为程序运行“太快”。
我没有太多的细节,所以如果你能告诉我们
Sources
和NormalReferenceSourceItems
中通常有多少项,那会很有帮助。我的理论是你的循环
字符串
在你有时间注意文本框中的变化之前就完成了。现在,如果你已经尝试过延迟或类似的事情,那么我会很有帮助。你能够看到
string.empty
的最终变化是因为它是最后一次,因此是永久性的变化。这可能都是错误的,但在这种情况下,如果你给予给我们一个在测试运行中传递到方法中的数据的种类/大小的概述,我将不胜感激。