以下方法如何更好地执行?
首先是一些背景信息:
表单和使用的逻辑(在更深层上)之间的映射放在字典 CtrlLogicMapping 中。
一个控件可以有多个逻辑(例如,用于表单上的不同控件)。
在某些情况下,有必要知道一个对象是否已经在一个(独立于哪个)控制逻辑中使用。
每个逻辑都可以有一个或多个映射的对象范围,这些对象范围来自第三方供应商,并包含有关映射到 db 的对象的信息。
如果使用了对象,则 aLogic.ObjectScope.IsUsed(ObjectID) 可能返回 true 或 false。
我想要一个方法,它询问每个现有的 ObjectScope 一旦对象是否在其中,并且一旦 objectscope 具有对象 true 就应该返回(不再需要处理其他 objectscope。一个 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
到目前为止的解决方案:感谢斯蒂芬博格
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;