改进了在 C# GDI 中绘制的循环
本文关键字:绘制 循环 GDI | 更新日期: 2023-09-27 18:32:31
我得到了一个 for 循环,它必须运行 200,000 次调用图形。画线。这非常慢,我期待您帮助提高此循环的性能。当我尝试任务并行性时,它会给出错误"调用线程必须是 STA,因为许多 UI 组件都需要这个。我还尝试将循环一分为二并并行执行它们,这也会导致相同的错误。我已经删除了与该尝试相关的代码,并给出了必须针对性能进行优化的实际代码。
代码是
从数组列表中获取数据,数组列表是图形的数据点
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.");
}
}
您应该尝试绘制到图像。为此,您需要从位图创建自己的图形上下文。
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