struck while converting into Parallel.ForEach

jasneet

Member
Joined
Nov 20, 2014
Messages
5
Programming Experience
1-3
I have below two functions, function Runtest is running foreach and taking too much time to complete.
I am thinking to covert the foreach loop to run parallel and using Parallel.ForEach, but seeing below two issue:


1. The issue is in current implementation GetHighestPriority function is using reference (ref failedCheck) ,
and setting its value, which will be used in second iteration of for loop and each time the loop execute will call GetHighestPriority
function with previous value of ref failedCheck.
2. the second issue is also similar GetHighestPriority function retuning the result and storing in aggResult ,
which is used by next for iteration loop and so on.

so the problem is how to handle GetHighestPriority function call in parallelism model , if any one suggest what is the best approach to handle parallelism
in this case will be great help for me.

        protected ActionResult Runtest(ref CheckTest failedCheck, CancellationToken token, bool logOnError, bool logOnSuccess)
        {
            Dictionary<string, string> fields = new Dictionary<string, string>(m_fields);


            ActionResult aggResult = new ActionResult(ActionStatus.Success);
            foreach (CheckWatcher watcher in CheckTestWatchers.Values)
            {
                if (token.IsCancellationRequested)
                    break;
               
                ActionResult result = watcher.ExecuteOnce();
                 fields[LogField.CheckKey] = watcher.Check.Key;
                fields[LogField.Reason] = result.Reason;
                Logger.Write(LogType.Info, "Hridyesh 1 {0} ", CheckTestWatchers.Values);
                if ((logOnError && result.Status != ActionStatus.Success) || (logOnSuccess && result.Status == ActionStatus.Success))
                {
                    fields[LogField.CheckKey] = watcher.Check.Key;
                    fields[LogField.Reason] = result.Reason;
                    Logger.Write(LogType.Info, fields, result.Status == ActionStatus.Success ? "Check succeeded" : "Check failed");
                }
                aggResult = GetHighestPriority(aggResult, result, ref failedCheck, watcher.Check as CheckTest);


                if (aggResult.Status == ActionStatus.NodeFail)
                {
                    break;
                }
            }
            return aggResult;
        }
        
         private ActionResult GetHighestPriority(ActionResult aggResult, ActionResult result, ref CheckTest failedCheck, CheckTest executingCheck)
        {
            if (aggResult.Status == ActionStatus.Success && result.Status != ActionStatus.Success)
            {
                failedCheck = executingCheck;
                return result;
            }
            else if (aggResult.Status == ActionStatus.ActionFail && (result.Status == ActionStatus.DependencyFail || result.Status == ActionStatus.NodeFail))
            {
                failedCheck = executingCheck;
                return result;
            }
            else if (aggResult.Status == ActionStatus.DependencyFail && result.Status == ActionStatus.NodeFail)
            {
                failedCheck = executingCheck;
                return result;
            }
            else if (aggResult.Status == ActionStatus.NodeFail && result.Status == ActionStatus.NodeFail && (!failedCheck.RequiresRotation && executingCheck.RequiresRotation) && !executingCheck.NoOpMode)
            {
                //a failed check that requires rotation is more important than one that doesn't if its not in NoOp mode
                failedCheck = executingCheck;
                return result;
            }
            return aggResult;
        }
 
Last edited by a moderator:

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
3,272
Location
Sydney, Australia
Programming Experience
10+
The first thing you need to do is identify whether each iteration needs data from the previous. If that is the case then parallelising the code is simply out of the question. That is inherently a serial operation.
 

jasneet

Member
Joined
Nov 20, 2014
Messages
5
Programming Experience
1-3
Thanks a lot .
Is it possible to get synchronized the data value among tasks. I am looking some example where i can share the values of aggResult and ref failedCheck in Runtest function .
Could you please give me some idea how to synchronized these two value between tasks during Parallel.ForEach ?
 
Top Bottom