Parallel.ForEach with tuple return c#

时间:2017-07-22 19:20:33

标签: c# multithreading foreach parallel-processing

基于这个example我试图通过元组返回来制作一个平行的foreach。

double min = double.MaxValue;

object syncObject = new object(); 
Parallel.ForEach(collection, () => double.MaxValue, (item, loopState, 
    localState) =>
    {
        double value = item.PerformComputation();
        return System.Math.Min(localState, value);
    },
    localState =>
    {
        lock(syncObj)
            min = System.Math.Min(min, localState);
    }
);

Console.Write(min + "\n");

上面的代码工作正常,但在我的场合(正确的最小值),但我不想输出最小值,但输出该值的'名称',所以我试过这样的事情:

double min = double.MaxValue;
string minName = "";

object syncObject = new object(); 
Parallel.ForEach(collection, () => Tuple.Create(double.MaxValue, ""), (item, 
    loopState, localState) =>
    {
        double value = PerformComputation(item.Item1.Value);
        string name = item.Item1.Key;

        return //helpHere
    },
    localState =>
    {
        lock(syncObj)
            min = //help here
            minName = //help here
    }
);

Console.Write(minName + "\n");

尝试了几件不起作用的事情。我也没有运气就读过microsoft's example。 任何帮助赞赏。

2 个答案:

答案 0 :(得分:5)

你的问题背景不是很多。你最好提供一个好的Minimal, Complete, and Verifiable code example来展示你正在做的事情。但是,它似乎就好像在您的第二个代码版本中,您已将计算模型从使用PerformComputation()方法的对象更改为本地的PerformComputation()方法已定义,以及某种Tuple对象的集合,其中Item1成员是某种KeyValuePair<TKey, TValue>

做出这些假设,这样的事情应该适用于你的场景:

Tuple<double, string> result = Tuple.Create(double.MaxValue, "");

object syncObject = new object(); 
Parallel.ForEach(collection, () => Tuple.Create(double.MaxValue, ""),
    (item, loopState, localState) =>
    {
        double value = PerformComputation(item.Item1.Value);

        if (value < localState.Item1)
        {
            localState = Tuple.Create(value, item.Item1.Key);
        }

        return localState;
    },

    localState =>
    {
        lock(syncObj)
        {
            if (localState.Item1 < result.Item1)
            {
                result = localState;
            }
        }
    }
);

答案 1 :(得分:2)

我不太确定我理解这个例子,但PLINQ会更容易:

string minName = collection.AsParallel()
     .Min(item => Tuple.Create(PerformComputation(item.Item1.Value), item.Item1.Key)).Item2;