I got a for loop which has to run 200,000 times calling graphics.DrawLine. This is very slow and I look forward for your help in increasing the performance of this loop. when I tried, Task Parallellism, it will give the error"The calling thread must be STA, because many UI components require this." I have also tried splitting the loop into two and execute them parallel, that also results in the same error. I have removed the code related to that attempts and have given the actual code which has to be optimized for performance.
The code is
// Take data from arraylist which is the data points for the graph
Graphics g = null;
public Drawing(Graphics _g, DrawingData _Data)
{
g = _g;
drawingData = _Data;
}
private void FrameDrawLine1()
{
DataValueSet pds = null;
DataValueSet ds = null;
for (int i = 1; i < drawingData.data.Count; i++) // the count will be 100,000
{
ds = (DataValueSet)drawingData.data[i];
PlotColumne(pds, ds);
}
}
// Get the color and other informtion about the graph parameters
private void PlotColumne(DataValueSet pds, DataValueSet ds)
{
try
{
double totalSeconds = (drawingData.valueArea.maxDate - drawingData.valueArea.minDate).TotalSeconds;
double xFrom = GetTimePixel(pds.time, totalSeconds);
double xTo = GetTimePixel(ds.time, totalSeconds);
PlotprintingDataset[] pt = initialisePlotprintingDataset();
_referenceColumnindex++;
PlotColumn column = null;
for (int i = 0; i < drawingData.plotColumns.Count; i++) // this count will be around 50
{
column = (PlotColumn)drawingData.plotColumns[i];
if (column.active)
{
if (ValueIsNumber(Convert.ToDouble(ds.values[column.index]), Convert.ToDouble(pds.values[column.index])))
{
if (pt[column.index].X < -10000F)
{
pt[column.index].X = xFrom;
pt[column.index].Y = calculateYValueInGraph(column, Convert.ToDouble(pds.values[column.index]));
}
if (DrawLineInGraph(pds, ds, column, pt))
{
pt[column.index].X = xTo;
pt[column.index].Y = calculateYValueInGraph(column, Convert.ToDouble(pds.values[column.index]));
}
}
}
}
}
catch (Exception ex)
{
GenericFunctions.ErrorMessage("Error has occured while plotting graph columns. Please try again.");
}
}
// Check if the point is in graph area and will call draw line method
private bool DrawLineInGraph(DataValueSet pds, DataValueSet ds, PlotColumn column, PlotprintingDataset[] pt)
{
double totalSeconds = (drawingData.valueArea.maxDate - drawingData.valueArea.minDate).TotalSeconds;
double xTo = GetTimePixel(ds.time, totalSeconds);
double value = Convert.ToDouble(ds.values[column.index]);
double y2 = calculateYValueInGraph(column, Convert.ToDouble(ds.values[column.index]));
double y1 = calculateYValueInGraph(column, Convert.ToDouble(pds.values[column.index]));
if (IsPointInPlausibleArea(pt, column, pds, ds))
{
drawLine(column.color, pt[column.index].X, xTo, pt[column.index].Y, y2, column.interpolate, column.lineWidth);
return true;
}
else
{
return false;
}
}
// Draw the lines in the graph
private void drawLine(Color color, double xFrom, double xTo, double yFrom, double yTo,
bool interpolate, int lineWidth)
{
try
{
System.Windows.Shapes.Line newline = new System.Windows.Shapes.Line();
Pen linePen = new Pen(new SolidBrush(color), lineWidth);
float x1 = (float)xFrom;
float x2 = (float)xTo;
float y1 = (float)yFrom;
float y2 = (float)yTo;
if (interpolate)
{
g.DrawLine(linePen, x1, y1, x2, y2);
}
else
{
g.DrawLine(linePen, x1, y1, x2, y1);
g.DrawLine(linePen, x2, y1, x2, y2);
}
}
catch (Exception ex)
{
GenericFunctions.ErrorMessage("Error has occured while drawing graph lines. Please try again.");
}
}