我有一種方法可以根據特定的(波形)函數(在下面的示例中我簡單地使用Math.Sin來簡化事情)生成(波形)位圖。到目前爲止,這種方法是「串行」(沒有線程),但使用的一些功能相對耗時,所以我嘗試使用Parallel.For
和Parallel.ForEach
,但我猜我使用的索引變量必須「損壞」(或至少有另一個值比我所期望的)要生成的圖形要麼包含「尖峯」,要麼包含非相鄰點之間的奇怪線條。在並行中使用索引器的正確方法。對於
這裏首先是我的串行版本(工作):
Point[] points = new Point[rect.Width];
byte[] ptTypes = new byte[rect.Width];
for (int i = 0; i < rect.Width; i++)
{
double phase = MathUtil.WrapRad((MathUtil.PI2/(rect.Width/1d)) * i);
double value = waveform.ValueAtPhase(phase);
newPoint = new Point(rect.Left + i,
rect.Top + (int) (halfHeight + (value * -1d * halfHeight * scaleY)));
points[i] = newPoint;
if (i == 0)
ptTypes[i] = (byte)PathPointType.Start;
else
ptTypes[i] = (byte)PathPointType.Line;
}
using (GraphicsPath wavePath = new GraphicsPath(points, ptTypes))
{
gph.DrawPath(wavePen, wavePath);
}
正如你所看到的代碼只需使用2點陣列(一個點,一個用於PointTypes)所以這些值插入順序數組無關緊要,只要將值插入數組的正確元素即可。
下一頁示例是使用的Parallel.For(爲了簡化實施例I省略了陣列的創建和實際拉制法):
Parallel.For(0, rect.Width,
i =>
{
double phase = MathUtil.WrapRad((MathUtil.PI2/(rect.Width/1d)) * i);
double value = Math.Sin(phase);//waveform.ValueAtPhase(phase);
newPoint = new Point(rect.Left + i,
rect.Top + (int)(halfHeight + (value * -1d * halfHeight * scaleY)));
points[i] = newPoint;
if (i == 0)
ptTypes[i] = (byte)PathPointType.Start;
else
ptTypes[i] = (byte)PathPointType.Line;
});
最後我嘗試使用一個分區程序與Parallel.ForEach環,但這並沒有解決問題或者:
var rangePartitioner = Partitioner.Create(0, rect.Width);
Parallel.ForEach(rangePartitioner, (range, loopState) =>
{
for (int i = range.Item1; i < range.Item2; i++)
{
double phase = MathUtil.WrapRad((MathUtil.PI2/(rect.Width/1d)) * i);
double value = Math.Sin(phase);//waveform.ValueAtPhase(phase);
newPoint = new Point(rect.Left + i,
rect.Top + (int)(halfHeight + (value * -1d * halfHeight * scaleY)));
points[i] = newPoint;
if (i == 0)
ptTypes[i] = (byte)PathPointType.Start;
else
ptTypes[i] = (byte)PathPointType.Line;
}
});
佩爾
有什麼問題? –