静态方法在多线程访问时变慢

时间:2012-06-07 10:25:35

标签: c# .net task-parallel-library

我遇到的情况是我的.Net 4的C#应用​​程序正在访问静态类中的静态方法,这使得该方法的执行速度比单个线程访问时要慢。比方说,如果方法由单个线程调用,则需要大约1.5分钟才能完成,而当由2个线程调用时,需要4分钟才能完成。

高度赞赏任何提高效果的想法/建议/最佳做法。提前感谢您的回复。

更多信息: 这是一个早期使用线程池在某些部分执行线程的应用程序。我介绍了并行任务。因此,它是TPL和旧线程池的混合。比如说一个并行任务可以有多个线程。该机器有24个CPU内核和64GB RAM。我运行了2个进程,这些进程将分成5个线程,每个进程总共最多10个线程。在此过程中,这个过程变慢了。我在这里粘贴代码,以便那些想要检查它并提供建议的人。很抱歉粘贴长代码。该代码可能没有具有所有当前最新功能,因为这是几年前编码的。再次感谢。

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;
                                currentWorks

1 个答案:

答案 0 :(得分:5)

静态方法没有任何内在,当多个线程访问它时会使它变慢,除非例如:

  • 您有一些节流的共享资源,例如共享lock,或者转到单个UI线程
  • 你拥有的线程多于可用的CPU核心,而且只需要进行大量的切换
  • 您正在最大限度地利用其他资源,例如磁盘IO,网络IO等

由于您尚未发布任何代码,我们只能猜测。