我有一个for循环,它必须运行200,000次调用graphics.DrawLine。这非常慢,我期待着您在提高此循环性能方面的帮助。当我尝试使用Task Parallellism时,它会给出错误"调用线程必须是STA,因为许多UI组件都需要这个。"我也试过将循环分成两个并且并行执行它们,这也会导致相同的错误。我删除了与该尝试相关的代码,并给出了必须针对性能进行优化的实际代码。
代码是
//从arraylist中获取数据,这是图表的数据点
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);
}
}
//获取有关图形参数的颜色和其他信息
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.");
}
}
//检查点是否在图形区域中并调用绘制线方法
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;
}
}
//在图表中绘制线条
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.");
}
}
答案 0 :(得分:0)
您应该尝试绘制图像。要执行此操作,您需要从位图创建自己的图形上下文。
Bitmap yourBitmap = new Bitmap(your controls width, height, PixelFormat. Format32bppArgb)
GRAPHICS G = Graphics.FromImage(yourBitmap)
// Draw your lines here
最后,您必须使用原始图形上下文将图片绘制到控件中。 e.Graphics.DrawImageUnscaled(0,0,yourBitmap)
此外,您可以调整图形上下文的参数。它们对性能也有很大的影响。
这是指向这些参数的链接:https://stackoverflow.com/a/38262796/6439999