This is a migrated thread and some comments may be shown as answers.

Different behavior when I specify a LineSeriesDefinition

2 Answers 73 Views
Chart
This is a migrated thread and some comments may be shown as answers.
Mike
Top achievements
Rank 1
Mike asked on 03 May 2009, 11:10 PM
I've got 3 charts in my app. When I don't specify a series.Definition, it works great. When I do, I find that it locks up my app if I call DataSeries.Clear() or if I try to replace a data series. I found a kludgey work-around by calling DataSeries.Reset(), then re-adding the data series, however, I'm seeing a lot of overhead with this method.

When I tried to create my DataSeries on a background thread, then call Dispatcher.BeginInvoke() to update the graph on the UI, I'm getting, "The calling thread cannot access this object because a different thread owns it." If I remove the series.Defintion and have the graph draw as a bar graph instead of a line graph, there are no problems whatsoever.

I'm supposed to be showing this at a trade show tomorrow and I'm stuck. It appears that when I specify a LineSeriesDefinition, a new thread internal to the control is introduced into the equation and it's wreaking havoc. Help!

Below is some of the code.

StartUpdatingCharts() is called from a timer:

protected void StartUpdatingCharts(object dummy)

{

    foreach (object currentGraph in ActiveGraphs)

    {

        Thread t = new Thread(UpdateChartInBackground);

        t.Start(currentGraph);

    }

}


public void UpdateChartInBackground(Object threadContext)

{

    GraphControl currentGraph = threadContext as GraphControl;

    FillChartWithData(currentGraph);

}




FillChartWithData() is called from a background thread:

protected override void FillChartWithData(GraphControl graphControl)

{

    Dictionary<string, double> returnValues = Msi.GetReservoirData(graphControl.Arguments);

    DataSeries series = new DataSeries();

    series.Definition.ShowItemLabels = false;

    LineSeriesDefinition definition = new LineSeriesDefinition();

    definition.ShowItemLabels = false;

    definition.ShowPointMarks = false;

    //series.Definition = definition;  //THIS IS THE LINE THAT CAUSES ALL OF THE PROBLEMS!

 


    foreach (string sectionName in returnValues.Keys)

    {

        series.Add(new DataPoint(returnValues[sectionName]));

    }


    ChartArea
chartArea = graphControl.RadChart.DefaultView.ChartArea;

    chartArea.Dispatcher.BeginInvoke(new UpdateChart(BindDataToChart), chartArea, series);

}

 


private
delegate void UpdateChart(ChartArea chartArea, DataSeries series);


private static void BindDataToChart(ChartArea chartArea, DataSeries series)

{

 

    chartArea.DataSeries.Clear();

    chartArea.DataSeries.Add(series);

}

 

 

2 Answers, 1 is accepted

Sort by
0
Ves
Telerik team
answered on 04 May 2009, 10:25 AM
Hello Mike,

This has already been fixed -- you can download the latest internal build from your account and give it a try. However, in this case, you might prefer to use a single LineSeriesDefinition object - you can initialize the RadChart.DefaultSeriesDefinition with an instance of LineSeriesDefinition and reuse it later:

When the chart is initialized:
myGraphControl.RadChart.DefaultSeriesDefinition = new LineSeriesDefinition() { ShowItemLabels = false };

And then in FillChartWithData():
series.Definition = graphControl.RadChart.DefaultSeriesDefinition;

I have attached a small example based on your code, built against the latest official version. Hope this helps.

Kind regards,
Ves
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
Mike
Top achievements
Rank 1
answered on 06 May 2009, 09:37 PM
I figured it out with the help of my boss (who knows a lot more about threading than I do). I was creating a DataSeries on the background thread and then assigning it to the chart. Apparently, you can't use an object in the UI thread unless it's created in the UI thread. Who knew? Anyway, I changed the code to retrieve the data on the background thread, then create my DataSeries on the foreground thread and copy the data into it there.  Presto, works like a charm!

Thanks for the excellent response time. We got it figured out in time for the second day of the show and things have gone fantastically well since then.

Mike
Tags
Chart
Asked by
Mike
Top achievements
Rank 1
Answers by
Ves
Telerik team
Mike
Top achievements
Rank 1
Share this question
or