Suppose we have a big count of the record in any object (I took CRM fetch XML response) which we want to iterate and do something. Below is the way through which you can perform Parallel Foreach record, which will improve the performance of the code.
using System.Collections.Concurrent;
using System.Threading.Tasks;
int hour = 1136;
int failCount = 0;
IOrganizationService service = GetService();
var fetchXmlCount = @"<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>" +
"<entity name='monlog'>" +
"<attribute name='name' />" +
"<attribute name='failcount' />" +
"<filter type='and'>" +
"<condition attribute='createdon' operator='last-x-hours' value='" + hour +"' />" +
"<condition attribute='failcount' operator='gt' value='0' />" +
"</filter>" +
"</entity>" +
"</fetch>";
EntityCollection monitorCount = service.RetrieveMultiple(new FetchExpression(fetchXmlCount));
System.Console.WriteLine("Count Started for number of records: " + monitorCount.Entities.Count);
// we will not use simple foreach loop as below, we will write Parllel Foreach loop
//foreach (var count in monitorCount.Entities)
//{
// failCount = failCount + Convert.ToInt32(count["ofs_failcount"]);
//}
// Use ConcurrentQueue to enable safe enqueueing from multiple threads.
var exceptions = new ConcurrentQueue<Exception>();
// Execute the complete loop and capture all exceptions if any.
Parallel.ForEach(monitorCount.Entities, (count) =>
{
try
{
failCount = failCount + Convert.ToInt32(count["failcount"]);
}
// Store the exception and continue with the loop.
catch (Exception ex)
{
exceptions.Enqueue(ex);
}
});
// Throw the exceptions here after the loop completes.
if (exceptions.Count > 0) throw new AggregateException(exceptions);
System.Console.WriteLine("Count of all Monitor Logs: " + failCount);
System.Console.ReadKey();
*This post is locked for comments