Good day,
I am attempting to speed up the processing of 5000 rows received from the database, render as a crystal report, export to byte stream and then save that byte stream in a database table. Currently I am using parallel.ForEach on a datatable. This uses 40 parallel processes that then sequentially iterates 125 (i.e 5000/40) records of the 5000 rows. It take approximately 5 minutes to do 5000 at the moment. Please assist on any suggestions on how to speed this up.
DataTable dtBills = new DataTable("dtBills");//I used an OdbcDataAdapter to fill this with 5000 records
private void ParallelProcess()
{
int numbills = 5000;
int numprocesses = 40;
int numsequential = numbills / numprocesses;
int p=0;
if (numbills < numprocesses)
p = numbills;
else
p = numprocesses;
Parallel.For(1, p+1, new ParallelOptions { MaxDegreeOfParallelism = 40 }, i =>
{
SequentialProcess(numsequential,i);
});
}
private void SequentialProcess(int batch,int num)
{
ReportDocument cryRpt = new ReportDocument();
cryRpt.Load(Application.StartupPath + "\\" + "Bill.rpt");
foreach(DataRow drow in dtBills.Rows.Cast<System.Data.DataRow>().Skip((num - 1) * batch).Take(batch).CopyToDataTable().Rows)
{
cryRpt.SetParameterValue(..... //here I set Crystal report Parameter values
Stream stream = cryRpt.ExportToStream(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat);
byte[] contents = new byte[stream.Length];
stream.Read(contents, 0, (int)stream.Length);
stream.Close();
if (!string.IsNullOrEmpty(sconnstr))
{
using (SqlConnection sconn = new SqlConnection(sconnstr))
{
String qry = @"INSERT INTO ....."
using (SqlCommand cmd = new SqlCommand(qry, sconn))
{
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue(// Set values for insert here one of which will be contents
cmd.Connection = sconn;
sconn.Open();
cmd.ExecuteNonQuery();
sconn.Close();
}
}
}
}
cryRpt.Close();
cryRpt.Dispose();
}
Any assistance will be greatly appreciated