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

本文关键字:访问 线程 静态方法 | 更新日期: 2023-09-27 18:36:30

我遇到这样一种情况:我的 .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

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

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

  • 您有一些共享资源正在受到限制,例如共享lock,或转到单个 UI 线程
  • 您的线程数比可用的CPU内核多,只需进行大量切换
  • 即可
  • 您正在最大化其他一些资源,例如磁盘 IO、网络 IO 等

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