我在写一篇文章
WPF
应用(
MVVM
模式使用
MVVM Light Toolkit
)读取和显示我公司使用的一系列内部日志文件。其目的是从多个文件中读取,从每行中提取内容,将它们放入类对象中,并将所述对象添加到
ObservableCollection
. 我已经设定了
ItemsSource
A的
DataGrid
在我身上
GUI
以使其以整洁的行和列显示数据。我有一个
ProgressBar
第二个窗口中的控件,在文件读取和显示过程中将更新进度。
安装程序
请注意,所有这些方法都被简化为删除所有不相关代码位的要点。
加载按钮
当用户选择包含日志文件的目录并单击此按钮时,过程开始。我打开装有
进度条
在这一点上。我用
BackgroundWorker
对于这个过程。
public void LoadButtonClicked()
{
_dialogService = new DialogService();
BackgroundWorker worker = new BackgroundWorker
{
WorkerReportsProgress = true
};
worker.DoWork += ProcessFiles;
worker.ProgressChanged += Worker_ProgressChanged;
worker.RunWorkerAsync();
}
processfiles()方法
这读数
全部的
选定目录中的文件,并逐个处理它们。在这里,当启动进度条窗口时,我正在使用
Dispatcher.Invoke()
.
private void ProcessFiles(object sender, DoWorkEventArgs e)
{
LogLineList = new ObservableCollection<LogLine>();
System.Windows.Application.Current.Dispatcher.Invoke(() =>
{
_dialogService.ShowProgressBarDialog();
});
var fileCount = 0;
foreach (string file in FileList)
{
fileCount++;
int currProgress = Convert.ToInt32(fileCount / (double)FileList.Length * 100);
ProcessOneFile(file);
(sender as BackgroundWorker).ReportProgress(currProgress);
}
}
processOneFile()方法
顾名思义,它读取一个文件,逐行遍历,将内容转换为我的类对象,并将它们添加到列表中。
public void ProcessOneFile(string fileName)
{
if (FileIO.OpenAndReadAllLinesInFile(fileName, out List<string> strLineList))
{
foreach (string line in strLineList)
{
if (CreateLogLine(line, out LogLine logLine))
{
if (logLine.IsRobotLog)
{
LogLineList.Add(logLine);
}
}
}
}
}
所以这很好,并按我想要的方式显示我的日志。
问题
然而,
之后
显示它们,如果我滚动
数据网格
, the
GUI
挂起并给出以下异常。
System.InvalidOperationException:“itemsControl不一致
及其项源。有关更多信息,请参阅内部异常
信息。
在阅读了这篇文章之后,在谷歌的帮助下,我发现这是因为
LogLineList
与…不一致
项目源
导致冲突。
当前解决方案
我发现如果我输入代码行
ProcessOneFile
一秒钟内将类对象添加到列表中
调度器.invoke()。
它解决了我的问题。像这样:
if (logLine.IsRobotLog)
{
System.Windows.Application.Current.Dispatcher.Invoke(() =>
{
LogLineList.Add(logLine);
});
}
现在这又可以正常工作了,但问题是这样会大大减慢处理时间。以前,一个包含10000行的日志文件大约需要1秒,而现在它可能需要5-10倍的时间。
我是做错了什么事,还是应该这样做?有更好的方法来处理这个吗?