3

Based on this example I'm trying to make a parallel foreach with tuple return.

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

The above code works fine but in my occasion(correct minimum value) but i don't want to output the minimum value but the 'name' of that value so i tried something like this:

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

Tried couple things that didn't work. Also I've read microsoft's example without luck. Any help appreciated.

2 Answers 2

4

There's not very much context in your question. It would have been better for you to provide a good Minimal, Complete, and Verifiable code example that showed exactly what you're doing. But, it appears as though in your second version of the code, you have changed the computational model from an object with a PerformComputation() method, to a PerformComputation() method that is locally defined, and a collection of some kind of Tuple object, where the Item1 member is a KeyValuePair<TKey, TValue> of some sort.

Making those assumptions, something like this should work in your scenario:

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;
            }
        }
    }
);
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot. It helped me and I solved my problem. Sorry for not providing my code example correctly, net time i'll know.
2

I am not quite sure I understand the example, but should be easier with PLINQ:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.