通过查看Divide Foreach into threads sample
中指定的此解决方案我尝试使用此代码实现它:
foreach (Object vo in arrreclist)
{
msg = String.Empty;
objprocess.GetType().GetMethod("ProcessRecord").Invoke(objprocess, new Object[] { vo });
status = (StatusInfo)objprocess.GetType().GetProperty("status").GetValue(objprocess, null);
if (status.errcode != 0)
{
lngfailedcnt++;
WriteErrorLog();
}
else
{
lngsuccesscnt++;
lngInstanceSuccCount++;
}
lngcnt++;
if ((lngcnt % 10) == 0)
{
if (instanceId == 0)
{
schldr.ModifyJobhistoryForUploadFileRecCnt(Runid, (int)lngTotreccnt, lngfailedcnt, (int)(lngfailedcnt + lngsuccesscnt));
}
else
{
schldr.ModifyJobhistoryForUploadFileRecCnt(Runid, 0, lngfailedcnt, (int)(lngfailedcnt + lngsuccesscnt));
}
status = schldr.status;
if (status.errcode != 0)
{
if (!String.IsNullOrEmpty(Errorlogfile))
WriteErrorLog();
holdInstance = true;
break;
}
//Get Job Status
//If job was terminated then Update Batch and Job history with status as STOPPED
intstatus = schedulersvc.GetJobStatus(Runid);
status = schedulersvc.status;
if (status.errcode != 0)
{
WriteErrorLog();
holdInstance = true;
break;
}
if (intstatus == 1) //STOPPED
{
holdInstance = true;
break;
}
lngcnt = 0;
}
}
正在为break语句发送错误消息:
不能离开匿名方法或lambda表达式的主体
我的主要任务是并行化以下行:
objprocess.GetType().GetMethod("ProcessRecord").Invoke(objprocess, new Object[] { vo })
但其他人是家属如何实施?
答案 0 :(得分:1)
首先,并行化在ASP.NET中通常没有意义。如果您有许多用户访问您的网站,您通常更关心可扩展性(您可以同时为多少用户服务),而不是单个用户的原始性能。
如果不是你的情况,并行化可能对你有意义。
其次,你得到了这个错误,因为Parallel.ForEach()
不是一个循环(就语言而言)。并且break
出一个lambda没有任何意义。
要突破Parallel.ForEach()
,您可以使用ParallelLoopState.Break()
或ParallelLoopState.Stop()
(阅读文档以了解您真正想要的那些文件)。为此,您需要使用Parallel.ForEach()
的重载,为您提供ParallelLoopState
。
第三,Parallel.ForEach()
不支持ArrayList
是有充分理由的:这是因为你永远不应该使用它。如果您确实需要object
的列表,请使用List<object>
清楚地表明您确实不知道该类型。如果您不能(或不想)更改ArrayList
,则可以.Cast<object>()
使Parallel.ForEach()
(以及与IEnumerable<T>
一起使用的其他方法)接受它
第四,我认为仅仅ProcessRecord
的并行化是没有意义的。看起来status
会返回上一个ProcessRecord
的状态。如果您并行执行ProcessRecord
,则不再清楚哪一个是最后一个。
此外,您不应该认为某些方法不是线程安全的。你应该知道。如果你将一些你不知道的东西并行化是线程安全的,你可能会很难在以后调试bug。
第五,如果你想并行化循环的第一部分,我认为最好的选择是PLINQ。类似的东西:
var intermediateResults = source.AsParallel().Select(x => Process(x));
foreach (var intermediateResult in intermediateResults)
{
// the rest of the loop
}