Different behavior when I specify a LineSeriesDefinition

3 posts, 0 answers
  1. Mike
    Mike avatar
    4 posts
    Member since:
    Apr 2009

    Posted 03 May 2009 Link to this post

    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. Ves
    Admin
    Ves avatar
    2926 posts

    Posted 04 May 2009 Link to this post

    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.
  3. Mike
    Mike avatar
    4 posts
    Member since:
    Apr 2009

    Posted 06 May 2009 Link to this post

    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
Back to Top