在我的WPF应用程序中,我的ViewModel与ViewModelService进行通信,ViewModelService又会说出一个CalculationService来检索要在View中显示的已处理数据。我希望视图能够向用户报告完成百分比。我的问题有两个。
首先是这个逻辑应该在哪里? CalculationService是否应该负责报告进度以及实际结果,或者ViewModel服务是否计算进度百分比详细信息。
其次,我看到我可以使用TPL或使用ReactiveExtentions实现此目的。在我的情况下,我倾向于反应性扩展,计算服务的API和实现看起来像这样
//This is pseudo code, just aiming to show my intention here
IEnumerable<Output> Calculate(IEnumerable<Inputs> inputs){
List<Output> output = new List<Output>();
foreach(var input : inputs){
//long running calculation, which produces output
//outputs.Add(output)
}
}
假设如果我沿着Reactive路线走下去,我可以使用Reactive的OnNext来传输“Output”,当它们到达时我也可以使用Parallel.Foreach来获得性能。
有关此的任何想法或想法吗?
由于 凯
答案 0 :(得分:1)
我认为视图模型层可以计算进度。
以下是我将如何使用Rx:
首先创建一个Progress<T>
类,将Output
提升为可以报告自己进度的类型。
public class Progress<T>
{
public Progress(T value, int current, int total)
{
this.Value = value;
this.Current = current;
this.Total = total;
}
public T Value { get; private set; }
public int Current { get; private set; }
public int Total { get; private set; }
public double Percentage
{
get
{
return (double)this.Current / (double)this.Total;
}
}
}
现在你只需要Calculate
方法。
public IObservable<Progress<Output>> Calculate(IEnumerable<Inputs> inputs)
{
return
Observable
.Create<Progress<Output>>(o =>
{
var source = inputs.ToArray();
var total = source.Length;
return
source
.ToObservable()
.Select((x, n) =>
new Progress<Output>(LongRunningCalculation(x), n, total))
.Subscribe(o);
});
}
这不会带来任何性能提升,但我当然不会使用Parallel.ForEach
来获得任何改进。混合任务,枚举和可观察性并不是最好的。坚持一种范式总是更好。
以下是我将如何并行运行。
IObservable<Progress<Output>> Calculate(IEnumerable<Inputs> inputs)
{
return
Observable
.Create<Progress<Output>>(o =>
{
var source = inputs.ToArray();
var total = source.Length;
return
source
.ToObservable()
.SelectMany(x => Observable.Start(() => LongRunningCalculation(x)))
.Select((x, n) => new Progress<Output>(x, n, total))
.Subscribe(o);
});
}