0

通过查看将Foreach 划分为线程示例中指定的此解决方案

我试图用这段代码来实现它:

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 }) 

但是其他的都是依赖,那么如何实现呢?

4

1 回答 1

1

首先,并行化在 ASP.NET 中通常没有意义。如果您有很多用户访问您的网站,您通常更关心可伸缩性(您可以同时服务多少用户),而不是单个用户的原始性能。

如果这不是你的情况,并行化可能对你有意义。

其次,你得到了那个错误,因为Parallel.ForEach()它不是一个循环(就语言而言)。从lambdabreak中取出没有任何意义。

要摆脱Parallel.ForEach(),您可以使用ParallelLoopState.Break()or ParallelLoopState.Stop()(阅读文档以找出您真正想要的其中一个)。为此,您将需要使用 that 的重载Parallel.ForEach()来为您提供ParallelLoopState.

Parallel.ForEach()第三,不支持有一个很好的理由ArrayList:因为你永远不应该使用它。如果你真的想要一个objects 的列表,用List<object>它来表明你真的不知道类型。如果您不能(或不想)更改ArrayList,您可以使用.Cast<object>()make Parallel.ForEach()(和其他适用的方法IEnumerable<T>)接受它。

第四,我认为并行化只是ProcessRecord没有意义。看起来status返回最后一个的状态ProcessRecord。如果你ProcessRecord并行执行,那么就不再清楚哪一个是最后一个了。

此外,您不应该认为某些方法不是线程安全的。你应该知道。如果你并行化你不知道是线程安全的东西,你以后可能很难调试错误。

第五,如果您只想并行化循环的第一部分,我认为最好的选择是 PLINQ。就像是:

var intermediateResults = source.AsParallel().Select(x => Process(x));

foreach (var intermediateResult in intermediateResults)
{
    // the rest of the loop
}
于 2013-08-30T10:27:26.760 回答