首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用第三方物流的Parallel.ForEach时跟踪进度

使用第三方物流的Parallel.ForEach时跟踪进度
EN

Stack Overflow用户
提问于 2013-01-26 19:51:17
回答 3查看 11.4K关注 0票数 16

跟踪以下进度的最佳方法是什么?

代码语言:javascript
运行
复制
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 (当前/总),但我不希望使用任何会对并行度产生不利影响的内容。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-01-26 21:01:04

Jon的解决方案很好,如果你需要像这样简单的同步,你的第一次尝试应该几乎总是使用lock。但是,如果您认为锁定的速度太慢,您应该考虑使用Interlocked之类的工具。

在本例中,我将使用Interlocked.Increment递增当前计数,并将Progress更改为一个属性:

代码语言:javascript
运行
复制
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);
    }
});

此外,你可能想要考虑如何处理异常,我不确定以异常结束的迭代是否应该被算作完成。

票数 15
EN

Stack Overflow用户

发布于 2013-01-26 20:05:59

由于您只是执行一些快速计算,因此通过锁定适当的对象来确保原子性:

代码语言:javascript
运行
复制
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;
        }
    }});
票数 4
EN

Stack Overflow用户

发布于 2013-01-26 20:13:01

在主体中不使用任何阻塞的解决方案:

代码语言:javascript
运行
复制
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 => { }
);

然后,访问当前进度:

代码语言:javascript
运行
复制
(float)states.Sum(state => state.value) / total
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14536656

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档