跟踪以下进度的最佳方法是什么?
long total = Products.LongCount();
long current = 0;
double Progress = 0.0;
Parallel.ForEach(Products, product =>
{
try
{
var price = GetPrice(SystemAccount, product);
SavePrice(product,price);
}
finally
{
Interlocked.Decrement(ref this.current);
}});我希望将进度变量从0.0更新为1.0 (当前/总),但我不希望使用任何会对并行度产生不利影响的内容。
发布于 2013-01-26 21:01:04
Jon的解决方案很好,如果你需要像这样简单的同步,你的第一次尝试应该几乎总是使用lock。但是,如果您认为锁定的速度太慢,您应该考虑使用Interlocked之类的工具。
在本例中,我将使用Interlocked.Increment递增当前计数,并将Progress更改为一个属性:
private long total;
private long current;
public double Progress
{
get
{
if (total == 0)
return 0;
return (double)current / total;
}
}
…
this.total = Products.LongCount();
this.current = 0;
Parallel.ForEach(Products, product =>
{
try
{
var price = GetPrice(SystemAccount, product);
SavePrice(product, price);
}
finally
{
Interlocked.Increment(ref this.current);
}
});此外,你可能想要考虑如何处理异常,我不确定以异常结束的迭代是否应该被算作完成。
发布于 2013-01-26 20:05:59
由于您只是执行一些快速计算,因此通过锁定适当的对象来确保原子性:
long total = Products.LongCount();
long current = 0;
double Progress = 0.0;
var lockTarget = new object();
Parallel.ForEach(Products, product =>
{
try
{
var price = GetPrice(SystemAccount, product);
SavePrice(product,price);
}
finally
{
lock (lockTarget) {
Progress = ++this.current / total;
}
}});发布于 2013-01-26 20:13:01
在主体中不使用任何阻塞的解决方案:
long total = Products.LongCount();
BlockingCollection<MyState> states = new BlockingCollection<MyState>();
Parallel.ForEach(Products, () =>
{
MyState myState = new MyState();
states.Add(myState);
return myState;
},
(i, state, arg3, myState) =>
{
try
{
var price = GetPrice(SystemAccount, product);
SavePrice(product,price);
}
finally
{
myState.value++;
return myState;
}
},
i => { }
);然后,访问当前进度:
(float)states.Sum(state => state.value) / totalhttps://stackoverflow.com/questions/14536656
复制相似问题