提高方法的性能

本文关键字:性能 方法 高方法 | 更新日期: 2023-09-27 18:17:52

如何使以下方法性能更好?

首先介绍一些背景信息:

表单和使用逻辑之间的映射(在更深的层上)放在字典CtrlLogicMapping中。

一个控件可以有多个逻辑(例如一个表单上的不同控件)。

在某些情况下,有必要知道一个对象是否已经在一个(独立于哪个)控制逻辑中使用。

每个逻辑可以有一个或多个映射的对象范围,这些对象范围来自第三方供应商,包含映射到db的对象的信息。

如果使用了对象,则逻辑。objectscope . isused (ObjectID)可以返回true或false。

我想要一个方法,它询问每一个现有的ObjectScope对象是否在它,一旦对象范围有对象true应该返回(其他对象范围不再需要处理。一个ObjectScope可以包含多个logic

不是每个表单都需要逻辑(因此列表可以为空或空),也不是每个逻辑都需要objectscope(也可以为空或空列表)。

InUse方法可能需要一些时间(InUse在测试中需要60到140毫秒)。

所以我想尽量避免调用InUse,并且尽可能地将它并行化。

迭代解:

internal bool InUse (string ID_in){
        List<string> checked = new List<string>();
        if (null != frmLogicMapping && 0 < frmLogicMapping.Count)
        {
            foreach (List<Logic> logics in frmLogicMapping.Values)
            {
                if (null != logics && 0 < logics.Count)
                {
                    foreach (Logic aLogic in logics)
                    {
                        if (null != aLogic.ObjectScope)
                        {
                            if (!checked.Contains(aLogic.ObjectScope.ID)) 
                            {
                                // can take up to 140 ms
                                if (aLogic.ObjectScope.InUse(ID_in)) 
                                    return true;
                                checkeded.Add(aLogic.ObjectScope.ID);
                            }
                        }
                    }
                }
            }
        }
        return false;
   }

是否有一种方法可以用InUse==true应该立即返回true而其他处理不应该报告任何内容的停止条件来麻痹它?

或者它也可以用PLINQ来写?如何在PLINQ中处理空值?或者普通LINQ会是更好的选择吗?(甚至如何处理空值?)

我想做的是像

        if (null != frmLogicMapping&& 0 < frmLogicMapping.Count)
        {
            var objectscopes = frmLogicMapping.Values
                .Where(logics != null && logics.Count > 0)
                .SelectMany(logic => logic.ObjectScope)
                .Where(logic.ObjectScope!= null).ToList();
            bool returnValue = false;
            Parallel.ForEach(objectscopes, objectScope=>
            {
                if (objectScope.IsDirtyObject(objectID))
                {
                    returnValue  = true;
                }
            });
            return returnValue  ;
        }

但是不知何故我混淆了linq语句…我也不知道如何从并行foreach立即返回,或者如何将返回值标记为volatile

谢谢,Offler


目前的解决方案:感谢Stephen Borg

 if (null != objectScopes && 0 < objectScopes .Count)
        {
            System.Threading.Tasks.Task<bool>[] tasks = new System.Threading.Tasks.Task<bool>[objectScopes.Count];
            for (int i = 0; i < objectScope.Count; i++)
            {
                int temp= i;
                tasks[temp] = System.Threading.Tasks.Task.Factory.StartNew(() => { return objectScopes[temp].InUse(ID_in); }
                    , System.Threading.Tasks.TaskCreationOptions.LongRunning);
            }
            System.Threading.Tasks.Task.WaitAll(tasks);
            if (tasks.Any(x => x.Result == true))
            {
                return true;
            }
        } 
        return false;

提高方法的性能

另一个选择是创建一个方法来验证List列表,并使用System.Threading.Tasks。任务,查看这里:http://msdn.microsoft.com/en-us/library/system.threading.tasks.task.aspx.

你可以做类似的事情,结构方面:

<>之前函数DummyMethod = () =>{返回true;};//创建任务列表System.Threading.Tasks。Task[] tasks = new System.Threading.Tasks.Task[2];//第一个任务var firstTask = System.Threading.Tasks.Task.Factory.StartNew(() => DummyMethod(), TaskCreationOptions.LongRunning);tasks[0] = firstTask;//第二个任务var secondTask = System.Threading.Tasks.Task.Factory.StartNew(() => DummyMethod(), TaskCreationOptions.LongRunning);tasks[1] = secondTask;//启动所有System.Threading.Tasks.Task.WaitAll(任务);如果任务。Any(x => x. result)) {控制台。写("使用!");}之前在这种情况下,您需要循环任务结果并检查是否有任何返回值为真。这样做的好处是,所有的列表将在单独的线程中同时运行。