簡體   English   中英

使用TPL的Parallel.ForEach時跟蹤進度

[英]Track progress when using TPL's Parallel.ForEach

以下是跟蹤進度的最佳方法

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(當前/總)但我不想使用會對並行性產生負面影響的任何內容。

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);
    }
});

此外,您可能想要考慮如何處理異常,我不確定以異常結束的迭代應該計為完成。

由於您只是進行了一些快速計算,因此通過鎖定適當的對象來確保原子性:

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;
        }
    }});

一種不使用身體任何阻塞的解決方案:

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) / total

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM