我有一个引用单独程序集的WPF项目。在引用的程序集中,我有一个类,负责从文本文件中提取一些数据。让我们说它逐行读取文件,所以我可以通过比较它的总线与总线数来计算完成百分比。
在WPF应用程序中,我有一个进度条,并创建了一个绑定到ViewModel属性的数据来存储进度。
如何从外部程序集获取进度以更新ViewModel属性,以便在UI中更新我的进度条“视图”?
BTW :引用的程序集,我可以访问源代码并可以更改/添加代码。一切都是.NET 4.5或更高版本。
答案 0 :(得分:3)
听起来很适合IProgress。
Here是如何使用它的示例。
一些伪代码:
public void DoWorkWithFile(IProgress<double> progress)
{
var lines = File.ReadAllLines("path to a file");
for (int i = 0; i < lines.Length; i++)
{
// do stuff with the line
progress.Report(100 * i / (double)lines.Length);
}
}
请注意,如果文件很大,ReadAllLines
将占用大量内存,因此不应该使用它。
如果您碰巧知道文件中的行数,则可以选择
public async Task DoWorkWithFileAsync(IProgress<double> progress)
{
using (var reader = new StreamReader(File.OpenRead("path to a file")))
{
var totalLines = (double)55; // Assuming you know it
var lineNo = 0;
string line;
while ((line = await reader.ReadLineAsync().ConfigureAwait(false)) != null)
{
// do stuff with the line
lineNo++;
progress.Report(100 * lineNo / totalLines);
}
}
}
答案 1 :(得分:1)
根据您的编辑解释,您可以更改其他程序集中的代码,我建议您采用我偏爱的方法:
// This would be in the external assembly
public MyReturnValue ProcessFile(Action<double> progressDelegate)
{
foreach(var line in file)
{
progressDelegate?.Invoke(myCalculatedProgress)
}
}
// This would be in the app
var progDelegate = new Action<double>((progress) => ViewModel.Progress = progress);
ExternalLibrary.ProcessFile(progDelegate);
当然,这只是我快速整理并且需要适应你的项目的东西,但这是我以前雇主在相当大的WPF项目中使用的东西,它运作得很好。
你需要照顾所有常见的嫌疑人,例如将更新发送到UI线程,但这都是相当标准的。
我们还使用IProgress接口来传递实际对象以报告这些事情,而无需到处查看代理人;这特别用于在我们使用的全局IProgress范围调出任何内容时显示模态对话框。