以下方法如何表现更好?
首先是一些背景信息:
表单和使用过的逻辑之间的映射(在更深层上)放在字典CtrlLogicMapping中。
控件可以有多个逻辑(例如,表单上的不同控件)。
在某些情况下,有必要知道一个物体已经在一个(独立的)控制逻辑中使用了。
每个逻辑都可以有一个或多个映射的对象范围,它们来自第三方供应商,包含有关映射到db的对象的信息。
如果使用了某个对象,则aLogic.ObjectScope.IsUsed(ObjectID)可能返回true或false。
我想要一个方法,一旦对象进入其中,就会询问每个现有的ObjectScope,并且只要对象镜具有对象为true,就应该返回(其他对象镜不再需要处理.AbreadScope可以是多个逻辑。
并非每个表单都需要逻辑(因此列表可以为null或为空)并且并非每个逻辑都需要一个objectcope(也可以是列表可以为null或空)。
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返回,或者如何将returnvalue标记为volatile
Thanxs,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;
答案 0 :(得分:2)
另一种选择是创建一个验证List列表的方法,并使用System.Threading.Tasks.Task,在此处查看:http://msdn.microsoft.com/en-us/library/system.threading.tasks.task.aspx。
你可以做一些与结构相似的事情:
Func DummyMethod = () =>{ return true; }; // Create list of tasks System.Threading.Tasks.Task[] tasks = new System.Threading.Tasks.Task[2]; // First task var firstTask = System.Threading.Tasks.Task.Factory.StartNew(() => DummyMethod(), TaskCreationOptions.LongRunning); tasks[0] = firstTask; // Second task var secondTask = System.Threading.Tasks.Task.Factory.StartNew(() => DummyMethod(), TaskCreationOptions.LongRunning); tasks[1] = secondTask; // Launch all System.Threading.Tasks.Task.WaitAll(tasks); if (tasks.Any(x => x.Result)) { Console.Write("In use!"); }
在这种情况下,您需要循环任务结果并检查是否有任何返回值为true。获得的是所有列表将在单独的线程上一次运行。