首页 > 解决方案 > Parallel for loop to add points to series resulting in index outside the bounds of array

问题描述

int signal_length=1000_000;
double[] x=new double[signal_length];

var Signal = new Series
{
    IsVisibleInLegend = true,
    ChartType = SeriesChartType.Line,
    LegendText = "Original Signal",
};

var options = new ParallelOptions() { MaxDegreeOfParallelism = 4 };
Parallel.For(0, x.Length,options, i =>
{
  Signal.Points.AddY(x[i]);
});

chart.Series.Add(Signal);

Error message:

System.IndexOutOfRangeException: 'Index was outside the bounds of the array.'

I think this error arise as the parallel loop not atomic
I want something like "REDUCTION" in c++

标签: c#multithreadingparallel-processingmschart

解决方案


图表控件不是线程安全的。您不能简单地从多个线程并行调用它的函数。

使用该DataBindY方法一次添加多个数据点。为了提高性能,这些DataBind*方法在内部使用SuspendUpdates/ResumeUpdates来防止在添加数据点时重绘图表。

不可能提高 Microsoft 如何实施他们的DataBind*方法的性能。


性能测量:

double[] x = new double[1_000_000];
Random r = new Random();

for (int i = 0; i < x.Length; i++)
{
    x[i] = r.NextDouble();
}

var Signal = new Series
{
    IsVisibleInLegend = true,
    ChartType = SeriesChartType.Line,
    LegendText = "Original Signal",
};

DateTime start = DateTime.Now;

Signal.Points.DataBindY(x);

DateTime end = DateTime.Now;

MessageBox.Show((end - start).TotalMilliseconds.ToString());

此代码显示,在我的计算机上使用DataBindY. 我看不出你如何改进这部分。

如果您发现实际绘制图表的性能很慢,则必须通过减少数据点的数量来寻求改进。例如,完全限制点数或仅包括每个第 n 个数据点。


推荐阅读