Click here to Skip to main content
15,886,067 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,

I have an application in C# 2010 and .Net 4.0 which uses multi threading through Task Parallel Library. There are some static classes and static methods within this. Whenever a static method is run in a single thread the performance is as expected but when the same method is called by different threads the method seems to get slower and this is impacting the overall performance of the application.

Any suggestion or best practices are highly appreciated. Thanks in advance of your responses.

Some more info:
This is an application which was using threadpool earlier to perform threading in some parts. I introduced parallel tasks. Hence it's a mix up of TPL and older Thread pool. Say for example one parallel task can have multiple threads. The machine has 24 CPU cores with 64GB RAM. I ran 2 processes which would have split to 5 threads each totalling upto 10 threads. During this the process got slower. I am pasting the code here for those who would like to inspect it and provide suggestions. Sorry for pasting long code. The code may not be having all current latest features as this was coded few years ago. Thanks once again.

C#
public static class Property11
    {
        /// <summary>
        /// Splits agg rows to separate commands where the reference parameters are included for each command.
        /// </summary>
        /// <param name="worksheetID">The current worksheet ID.</param>
        /// <param name="propertyID">The current property ID.</param>
        /// <param name="ccrFormObj">The ccr form object.</param>
        public static void SplitAggregateIncludeReferenceParameterCCRToDTH(PropertyCall propertyCallObj)
        {
            string worksheetID = propertyCallObj.WorksheetID;
            int propertyID = propertyCallObj.PropertyID;
            IDClass nextIDObj = propertyCallObj.NextIDObj;
            CCRFormStructure ccrFormObj = propertyCallObj.CCRFormObj;
            List<CCRFormStructure> ccrFormObjsToAdd = propertyCallObj.CCRFormObjToAddList;

            DateTime dtProp = DateTime.Now;
            System.Diagnostics.Debug.Print("Start time property = " + propertyCallObj.PropertyID + ", worksheet = " + propertyCallObj.WorksheetID + ": " + dtProp.ToString());

            try
            {
                // Get all rows for worksheet
                List<WorksheetRow> rowListForWorksheet =
                    (from wr in ccrFormObj.myWorksheetRowList
                     where wr.WorksheetID == worksheetID
                     select wr).ToList();

                // Get all parameters for worksheet
                List<WorksheetRowParameter> rowParameterListForWorksheet =
                    (from wrp in ccrFormObj.myWorksheetRowParameterList
                     join wr in rowListForWorksheet
                     on wrp.WorksheetRowID equals wr.ID
                     select wrp).ToList();

                // Get all agg rows in worksheet
                List<AggRow> aggRowsInWorksheet =
                    (from ar in ccrFormObj.myAggRowList
                     join wsrp in rowParameterListForWorksheet
                     on ar.WorksheetRowParameterID equals wsrp.ID
                     select ar).ToList();

                // Get all agg row parameters in worksheet
                List<AggRowParameter> aggParametersInWorksheet =
                    (from arp in ccrFormObj.myAggRowParameterList
                     join ar in aggRowsInWorksheet
                     on arp.AggRowID equals ar.ID
                     select arp).ToList();

                // Get all command mappings for worksheet
                List<CommandMappingObj> commandMappingListForWorksheet =
                    (from cm in ccrFormObj.commandMappingList
                     join wr in rowListForWorksheet
                     on cm.WorksheetRowID equals wr.ID
                     select cm).ToList();

                // Get all parameter mappings for worksheet
                List<ParameterMappingObj> parameterMappingListForWorksheet =
                    (from pm in ccrFormObj.parameterMappingList
                     join cm in commandMappingListForWorksheet
                     on pm.CommandMappingObjID equals cm.ID
                     select pm).ToList();

                // Get all property objects for  worksheet
                List<ParameterPropertyObj> propertyList =
                    (from ppo in ccrFormObj.parameterPropertiesList
                     where ppo.ID == propertyID && ppo.WorksheetID == worksheetID
                     select ppo).ToList();

                //List<WorksheetRow> rowsToRemove = new List<WorksheetRow>();  
                WorksheetRowParameter currentWorksheetRowParameter;
                AggRow currentAggRow;
                AggRowParameter currentAggRowParameter;
                AggRow currentSteeringAggRow;
                AggRowParameter currentSteeringAggRowParameter;
                int newIDIndex = 0;
                List<string> worksheetRowsWithoutTooLongCommandRows = new List<string>();
                WorksheetRow newWSR = new WorksheetRow();
                CommandMappingObj newCMO = new CommandMappingObj();
                WorksheetRow newWSRForOrigRow = new WorksheetRow();
                CommandMappingObj newChangeCMO = new CommandMappingObj();
                List<string> steeringParameters;
                IEnumerable<WorksheetRowParameter> parameterListForRow;
                IEnumerable<WorksheetRowParameter> currentSteeringParameters;
                string newCMOID;
                ParameterMappingObj newPMO;
                WorksheetRowParameter newWSRP;
                string newWSRID;
                string newID;
                IEnumerable<string> commandsWithPropertyParameterForRow;
                Hashtable htPropertyParamAndSteeringParameters = new Hashtable();
                List<string> steeringParametersForProperty;
                WorksheetRowParameter currentWorksheetRowPropertyParameter;
                bool removeOrigRow = false;
                bool firstRowForAggCreated = false;
                List<WorksheetRowParameter> propParamListForFirstCreatedRow = new List<WorksheetRowParameter>();
                List<string> propParamUsedAsSteeringList = new List<string>();

                foreach (ParameterPropertyObj propertyParameter in propertyList)
                {
                    if (propertyParameter.SecondaryPropertyInfo != null && propertyParameter.SecondaryPropertyInfo != "")
                    {
                        steeringParameters = propertyParameter.SecondaryPropertyInfo.Split(",".ToCharArray()).ToList();
                    }
                    else
                    {
                        steeringParameters = new List<string>();
                    }

                    htPropertyParamAndSteeringParameters.Add(propertyParameter.Parameter, steeringParameters);
                }

                var aggListForRow =
                    from ar in aggRowsInWorksheet
                    join arp in aggParametersInWorksheet
                    on ar.ID equals arp.AggRowID
                    select new
                    {
                        AggRow = ar,
                        AggRowParameter = arp
                    };

                var worksheetRowsWithRepParam =
                    from wrp in rowParameterListForWorksheet
                    where htPropertyParamAndSteeringParameters.Contains(wrp.Parameter)
                    join al in aggListForRow
                    on wrp.ID equals al.AggRow.WorksheetRowParameterID
                    into aggList
                    where aggList.Count() > 0
                    select new
                    {
                        WorksheetRowParameter = wrp,
                        AggList = aggList
                    };

                foreach (WorksheetRow worksheetRow in rowListForWorksheet.ToList())
                {
                    var worksheetRowWithRepParam =
                        worksheetRowsWithRepParam.Where(wrp => wrp.WorksheetRowParameter.WorksheetRowID == worksheetRow.ID);

                    if (worksheetRowWithRepParam.Count() > 0)
                    {
                        firstRowForAggCreated = false;

                        var currentMappingList =
                            from cmo in commandMappingListForWorksheet
                            where cmo.WorksheetRowID == worksheetRow.ID
                            join pmo in parameterMappingListForWorksheet
                            on cmo.ID equals pmo.CommandMappingObjID
                            into parameterMappingList
                            select new
                            {
                                CommandMapping = cmo,
                                ParameterMappingList = parameterMappingList
                            };

                        IEnumerable<ParameterPropertyObj> sortedPropertyList =
                            from wrwrp in worksheetRowWithRepParam
                            join ppo in propertyList
                            on wrwrp.WorksheetRowParameter.Parameter equals ppo.Parameter
                            orderby wrwrp.AggList.Count() descending
                            select ppo;

                        propParamUsedAsSteeringList.Clear();

                        foreach (ParameterPropertyObj ppo in sortedPropertyList)
                        {
                            if (!propParamUsedAsSteeringList.Contains(ppo.Parameter))
                            {
                                var currentWorksheetRowsWithRepParam =
                                    worksheetRowWithRepParam.Where(p => p.WorksheetRowParameter.Parameter == ppo.Parameter);

                                if (currentWorksheetRowsWithRepParam.Count() == 0)
                                {
                                    continue;
                                }

                                var currentWorksheetRowWithRepParam = currentWorksheetRowsWithRepParam.ElementAt(0);

                                var currentAggList = currentWorksheetRowWithRepParam.AggList;

                                if (!firstRowForAggCreated)
                                {
                                    currentWorksheetRowPropertyParameter = currentWorksheetRowWithRepParam.WorksheetRowParameter;
                                }
                                else
                                {
                                    currentWorksheetRowPropertyParameter = propParamListForFirstCreatedRow.Where(p => p.Parameter == ppo.Parameter).ElementAt(0);
                                }

                                if (currentAggList.Count() > 1)
                                {
                                    removeOrigRow = true;

                                    steeringParametersForProperty = (List<string>)htPropertyParamAndSteeringParameters[ppo.Parameter];

                                    currentSteeringParameters =
                                        from wrp in rowParameterListForWorksheet
                                        where wrp.WorksheetRowID == worksheetRow.ID
                                        && steeringParametersForProperty.Contains(wrp.Parameter)
                                        select wrp;

                                    commandsWithPropertyParameterForRow =
                                        from cml in currentMappingList
                                        where cml.ParameterMappingList.Count(pmo => pmo.Name == ppo.Parameter) > 0
                                        select cml.CommandMapping.Name;

                                    propParamUsedAsSteeringList.AddRange(
                                        from sp in sortedPropertyList
                                        where sp.Parameter != ppo.Parameter
                                        join csp in currentSteeringParameters
                                        on sp.Parameter equals csp.Parameter
                                        select csp.Parameter);

                                    // CREATE NEW WORKSHEET ROWS FOR EACH BUT THE FIRST AGG ROW PARAMETER
                                    for (int i = 0; i < currentAggList.Count(); i++)
                                    {
                                        currentAggRow = currentAggList.ElementAt(i).AggRow;
                                        currentAggRowParameter = currentAggList.ElementAt(i).AggRowParameter;

                                        if (i == 0)
                                        {
                                            currentWorksheetRowPropertyParameter.Value = currentAggRowParameter.Value;

                                            if (!firstRowForAggCreated)
                                            {
                                                propParamListForFirstCreatedRow.Clear();

                                                newWSRID = newIDIndex.ToString().PadLeft(3, '0');
                                                newID = newWSRID;

                                                if (!worksheetRow.ID.Contains(','))
                                                {
                                                    newID = "," + newWSRID;
                                                }

                                                newWSRForOrigRow = new WorksheetRow
                                                {
                                                    ID = worksheetRow.ID + newID,
                                                    OriginalWorksheetRowID = worksheetRow.OriginalWorksheetRowID,
                                                    WorksheetID = worksheetRow.WorksheetID
                                                };

                                                ccrFormObj.myWorksheetRowList.Add(newWSRForOrigRow);

                                                parameterListForRow =
                                                    from wrp in rowParameterListForWorksheet
                                                    where wrp.WorksheetRowID == worksheetRow.ID
                                                    select wrp;

                                                foreach (WorksheetRowParameter currentParameter in parameterListForRow)
                                                {
                                                    newID = "";

                                                    if ((currentParameter.ID != null) && (!currentParameter.ID.Contains(',')))
                                                    {
                                                        newID = ",";
                                                    }

                                                    newID += newIDIndex.ToString().PadLeft(3, '0');

                                                    newWSRP = new WorksheetRowParameter
                                                    {
                                                        ID = currentParameter.ID + newID,
                                                        OriginalParameterID = currentParameter.OriginalParameterID,
                                                        WorksheetRowID = newWSRForOrigRow.ID,
                                                        Parameter = currentParameter.Parameter,
                                                        Value = currentParameter.Value,
                                                        Disabled = currentParameter.Disabled
                                                    };

                                                    if (htPropertyParamAndSteeringParameters.Contains(newWSRP.Parameter)
                                                        && newWSRP.Parameter != ppo.Parameter)
                                                    {
                                                        // TODO: IF AGG, TAKE AGG POS VALUE

                                                        var steeringParamAggList =
                                                            from wrwrp in worksheetRowWithRepParam
                                                            where wrwrp.WorksheetRowParameter.Parameter == newWSRP.Parameter
                                                            select wrwrp.AggList;

                                                        if (steeringParamAggList.Count() > 0)
                                                        {
                                                            if (steeringParamAggList.ElementAt(0).Count() > i)
                                                            {
                                                                currentSteeringAggRow = steeringParamAggList.ElementAt(0).ElementAt(i).AggRow;
                                                                currentSteeringAggRowParameter = steeringParamAggList.ElementAt(0).ElementAt(i).AggRowParameter;

                                                                newWSRP.Value = currentSteeringAggRowParameter.Value;

                                                                ccrFormObj.myAggRowParameterList.Remove(currentSteeringAggRowParameter);
                                                                ccrFormObj.myAggRowList.Remove(currentSteeringAggRow);

                                                                ccrFormObj.myWorksheetRowParameterList.Add(newWSRP);
                                                            }
                                                        }
                                                        else
                                                        {
                                                            ccrFormObj.myWorksheetRowParameterList.Add(newWSRP);
                                                        }

                                                        propParamListForFirstCreatedRow.Add(newWSRP);
                                                    }
                                                    else
                                                    {
                                                        ccrFormObj.myWorksheetRowParameterList.Add(newWSRP);
                                                    }
                                                }

                                                foreach (var currentMapping in currentMappingList)
                                                {
                                                    // Re-point original command mapping to new row
                                                    newCMOID = newIDIndex.ToString().PadLeft(3, '0');

                                                    if (!currentMapping.CommandMapping.ID.Contains(','))
                                                    {
                                                        newID = "," + newCMOID;
                                                    }

                                                    // Create new command mapping object
                                                    newCMO = new CommandMappingObj
                                                    {
                                                        ID = currentMapping.CommandMapping.ID + newID,
                                                        Name = currentMapping.CommandMapping.Name,
                                                        WorksheetRowID = newWSRForOrigRow.ID
                                                    };

                                                    ccrFormObj.commandMappingList.Add(newCMO);

                                                    foreach (ParameterMappingObj pmo in currentMapping.ParameterMappingList)
                                                    {
                                                        newPMO = new ParameterMappingObj
                                                        {
                                                            Name = pmo.Name,
                                                            CommandMappingObjID = newCMO.ID
                                                        };

                                                        ccrFormObj.parameterMappingList.Add(newPMO);
                                                    }
                                                }

                                                firstRowForAggCreated = true;
                                            }
                                        }
                                        else
                                        {
                                            newWSRID = newIDIndex.ToString().PadLeft(3, '0');
                                            newID = newWSRID;

                                            if (!worksheetRow.ID.Contains(','))
                                            {
                                                newID = "," + newWSRID;
                                            }

                                            newWSR = new WorksheetRow
                                            {
                                                ID = worksheetRow.ID + newID,
                                                OriginalWorksheetRowID = worksheetRow.OriginalWorksheetRowID,
                                                WorksheetID = worksheetRow.WorksheetID
                                            };

                                            ccrFormObj.myWorksheetRowList.Add(newWSR);

                                            foreach (WorksheetRowParameter currentSteeringParameter in currentSteeringParameters)
                                            {
                                                newID = "";

                                                if ((currentSteeringParameter.ID != null) && (!currentSteeringParameter.ID.Contains(',')))
                                                {
                                                    newID = ",";
                                                }

                                                newID += newIDIndex.ToString().PadLeft(3, '0');

                                                newWSRP = new WorksheetRowParameter
                                                {
                                                    ID = currentSteeringParameter.ID + newID,
                                                    OriginalParameterID = currentSteeringParameter.OriginalParameterID,
                                                    WorksheetRowID = newWSR.ID,
                                                    Parameter = currentSteeringParameter.Parameter,
                                                    Value = currentSteeringParameter.Value,
                                                    Disabled = currentSteeringParameter.Disabled
                                                };

                                                var steeringParamAggList =
                                                    from wrwrp in worksheetRowWithRepParam
                                                    where wrwrp.WorksheetRowParameter.Parameter == newWSRP.Parameter
                                                    select wrwrp.AggList;

                                                if (steeringParamAggList.Count() > 0)
                                                {
                                                    if (steeringParamAggList.ElementAt(0).Count() > i)
                                                    {
                                                        currentSteeringAggRow = steeringParamAggList.ElementAt(0).ElementAt(i).AggRow;
                                                        currentSteeringAggRowParameter = steeringParamAggList.ElementAt(0).ElementAt(i).AggRowParameter;

                                                        newWSRP.Value = currentSteeringAggRowParameter.Value;

                                                        ccrFormObj.myAggRowParameterList.Remove(currentSteeringAggRowParameter);
                                                        ccrFormObj.myAggRowList.Remove(currentSteeringAggRow);

                                                        ccrFormObj.myWorksheetRowParameterList.Add(newWSRP);
                                                    }
                                                }
                                                else
                                                {
                                                    ccrFormObj.myWorksheetRowParameterList.Add(newWSRP);
                                                }
                                            }

                                            // Add rep param
                                            newID = "";

                                            if ((currentWorksheetRowPropertyParameter.ID != null) && (!currentWorksheetRowPropertyParameter.ID.Contains(',')))
                                            {
                                                newID = ",";
                                            }

                                            newID += newIDIndex.ToString().PadLeft(3, '0');

                                            newWSRP = new WorksheetRowParameter
                                            {
                                                ID = currentWorksheetRowPropertyParameter.ID + newID,
                                                OriginalParameterID = currentWorksheetRowPropertyParameter.OriginalParameterID,
                                                WorksheetRowID = newWSR.ID,
                                                Parameter = currentWorksheetRowPropertyParameter.Parameter,
                                                Value = currentAggRowParameter.Value,
                                                Disabled = currentWorksheetRowPropertyParameter.Disabled
                                            };

                                            ccrFormObj.myWorksheetRowParameterList.Add(newWSRP);

                                            foreach (var currentMapping in currentMappingList)
                                            {
                                                if (commandsWithPropertyParameterForRow.Contains(currentMapping.CommandMapping.Name))
                                                {
                                                    newCMOID = newIDIndex.ToString().PadLeft(3, '0');

                                                    if (!currentMapping.CommandMapping.ID.Contains(','))
                                                    {
                                                        newID = "," + newCMOID;
                                                    }

                                                    // Create new command mapping object
                                                    newCMO = new CommandMappingObj
                                                    {
                                                        ID = currentMapping.CommandMapping.ID + newID,
                                                        Name = currentMapping.CommandMapping.Name,
                                                        WorksheetRowID = newWSR.ID
                                                    };

                                                    ccrFormObj.commandMappingList.Add(newCMO);

                                                    foreach (ParameterMappingObj pmo in currentMapping.ParameterMappingList)
                                                    {
                                                        if ((pmo.Name == ppo.Parameter) || (currentSteeringParameters.Count(p => p.Parameter == pmo.Name) > 0))
                                                        {
                                                            newPMO = new ParameterMappingObj
                                                            {
                                                                Name = pmo.Name,
                                                                CommandMappingObjID = newCMO.ID
                                                            };

                                                            ccrFormObj.parameterMappingList.Add(newPMO);
                                                        }
                                                    }
                                                }
                                            }
                                        }

                                        newIDIndex++;

                                        ccrFormObj.myAggRowParameterList.Remove(currentAggRowParameter);
                                        ccrFormObj.myAggRowList.Remove(currentAggRow);
                                    }
                                }
                                else
                                {
                                    currentAggRow = currentAggList.ElementAt(0).AggRow;
                                    currentAggRowParameter = currentAggList.ElementAt(0).AggRowParameter;
                                    currentWorksheetRowPropertyParameter.Value = currentAggRowParameter.Value;

                                    ccrFormObj.myAggRowParameterList.Remove(currentAggRowParameter);
                                    ccrFormObj.myAggRowList.Remove(currentAggRow);
                                }
                            }
                        }

                        if (removeOrigRow)
                        {
                            FormLogicCommon.RemoveObjectsForWorksheetRow(worksheetRow, ref ccrFormObj);
                            removeOrigRow = false;
                        }
                    }
                }

                ccrFormObjsToAdd.Add(ccrFormObj);
            }
            catch (Exception exc)
            {
                if (exc.InnerException == null)
                    throw new Exception("", exc);
                else
                    throw exc;
            }
            finally
            {
                System.Diagnostics.Debug.Print("Processing time property = " + propertyID + ", worksheet = " + worksheetID + ": " + DateTime.Now.Subtract(dtProp));
            }
        }
    }
Posted
Updated 7-Jun-12 5:32am
v2
Comments
Rajeev Jayaram 7-Jun-12 11:47am    
Try to avoid pasting a lot of code. Be precise and that would fetch good results.

The simple answer is no, static classes and methods will not get slower when run on multiple threads. They really cannot. However, that doesn't mean that the resources they access won't run slower. For example, if each thread is downloading a file and the combined number of threads maxes out your network connection, each will perform slower than if they were each run seperately and had the full resources of the network connection to themselves. Threading works to make full use of your processor but sometimes your processor isn't the only limiting factor.
 
Share this answer
 
No, it doesn't. But, whatever you're using for a data store might not appreciate it.

I'm not about to go digging through that pile of code to find it either. My head exploded when I saw that. I think you REALLY need to try and break that down into smaller methods. You may find out that you can do some things in that pile on multiple threads, but not others.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900