Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parallel.ForEach with tuple return c#

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.


1 Answers

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;
            }
        }
    }
);
like image 179
Peter Duniho Avatar answered Jan 23 '26 16:01

Peter Duniho



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!