Domanda

By seeing this solution specified in Divide Foreach into threads sample

I tried to implement it with this code:

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

And error message is coming for break statement:

cannot leave the body of anonymous method or lambda expression

My major task is to parallelize the following line:

objprocess.GetType().GetMethod("ProcessRecord").Invoke(objprocess, new Object[] { vo }) 

But other are dependents so how to implement?

È stato utile?

Soluzione

First, parallelization often doesn't make sense in ASP.NET. If you have many users accessing your site, you usually care more about scalability (how many users can you serve at the same time), than raw performance for single user.

If that's not your case, parallelization might make sense for you.

Second, you're getting that error, because Parallel.ForEach() is not a loop (as far as the language is concerned). And breaking out of a lambda doesn't make any sense.

To break out of Parallel.ForEach(), you can use ParallelLoopState.Break() or ParallelLoopState.Stop() (read the documentation to find out which one of those do you actually want). To do this, you will need to use an overload of Parallel.ForEach() that gives you that ParallelLoopState.

Third, there is a good reason why Parallel.ForEach() doesn't support ArrayList: it's because you should never use it. If you really want a list of objects, use List<object> to make it clear that you really don't know the type. If you can't (or don't want to) change the ArrayList, you can use .Cast<object>() to make Parallel.ForEach() (and other methods that work with IEnumerable<T>) accept it.

Fourth, I think that parallelizing just the ProcessRecord doesn't make sense. It looks like status returns the status for the last ProcessRecord. And if you execute ProcessRecord in parallel, then it's not clear anymore which one is the last.

Also, you shouldn't think that some method is not thread-safe. You should know that. If you parallelize something that you don't know is thread-safe, you're likely to get hard to debug bugs later on.

Fifth, if you want to parallelize just the first part of a loop, I think the best option is PLINQ. Something like:

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

foreach (var intermediateResult in intermediateResults)
{
    // the rest of the loop
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top