如果我需要使用LINQ生成相当大的数据集,并且可能要花一些时间(例如几秒钟),并且我需要(希望)生成有关使用情况的反馈信息,是否有简单/首选的方法去做这个?
例如,假设我有1000辆汽车的列表A和1000辆卡车的列表B,并且我想选择所有可能的有序(汽车,卡车)对,其中car.color == truck.color链接如下:
var pairs = from car in A
from truck in B
where car.color==truck.color
select new {car, truck};
Run Code Online (Sandbox Code Playgroud)
现在,将在某些时候将其评估为一组嵌套的foreach循环。我希望能够报告完成的%%年龄,并且可以理想地更新进度条或其他内容。
编辑:查询后,我将结果存储在一个成员变量中,像这样的列表(这将强制执行查询):
mPairs = pairs.ToList();
Run Code Online (Sandbox Code Playgroud)
我这样做是因为我在后台工作线程中执行此操作,因为我不希望UI线程冻结,因为它会按需评估UI线程上的LINQ表达式(这在Silverlight BTW中)。因此,为什么我要报告进度。UX基本上是这样的:
(删除项目时必须执行类似的过程)
我使用的效果很好的是 DataContext 的适配器,它返回其生成的项目数。
public class ProgressArgs : EventArgs
{
public ProgressArgs(int count)
{
this.Count = count;
}
public int Count { get; private set; }
}
public class ProgressContext<T> : IEnumerable<T>
{
private IEnumerable<T> source;
public ProgressContext(IEnumerable<T> source)
{
this.source = source;
}
public event EventHandler<ProgressArgs> UpdateProgress;
protected virtual void OnUpdateProgress(int count)
{
EventHandler<ProgressArgs> handler = this.UpdateProgress;
if (handler != null)
handler(this, new ProgressArgs(count));
}
public IEnumerator<T> GetEnumerator()
{
int count = 0;
foreach (var item in source)
{
// The yield holds execution until the next iteration,
// so trigger the update event first.
OnUpdateProgress(++count);
yield return item;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
Run Code Online (Sandbox Code Playgroud)
用法
var context = new ProgressContext(
from car in A
from truck in B
select new {car, truck};
);
context.UpdateProgress += (sender, e) =>
{
// Do your update here
};
var query = from item in context
where item.car.color==item.truck.color;
// This will trigger the updates
query.ToArray();
Run Code Online (Sandbox Code Playgroud)
唯一的问题是,除非您知道总数,否则您无法轻松计算百分比。要进行总数计数通常需要处理整个列表,这可能会很昂贵。如果您事先知道总计数,则可以在 UpdateProgress 事件处理程序中计算出百分比。
| 归档时间: |
|
| 查看次数: |
3195 次 |
| 最近记录: |