Asynchronously loading a point in chart on drag I have some code that asynchronously loads some point in a chart when a users drag it:

private void UpdateHistoryAndReSizeWhenDrag(string param, long duration)
    {
        lock (Lock)
        {
            if (Boxes.Count() &gt; 0)
            {
                BoxStruct temp = Boxes.Where(key =&gt; key.id == param).FirstOrDefault();
                if (temp != null)
                {
                    int index = Boxes.IndexOf(Boxes.Where(key =&gt; key.id == param).First());
                    if (index &gt;= 0)
                    {
                        double ChartLastPoint = Boxes[index].Series.Points[0].X;
                        double LastShownPoint = (from x in Boxes where x.id == param select x.PlotModel.Axes[0].ActualMinimum).Min();
                        double PMActualMinimumY = (from x in Boxes where x.id == param select x.PlotModel.Axes[0].ActualMinimum).Min();
                        double PMActualMaximumY = (from x in Boxes where x.id == param select x.PlotModel.Axes[0].ActualMaximum).Max();
                        if (LastShownPoint &lt; ChartLastPoint)
                        {
                            string StartTime = (ConvertToUnixTime(DateTime.FromOADate(LastShownPoint)) - (10800 + duration * 4)).ToString();
                            string EndTime = (ConvertToUnixTime(DateTime.FromOADate(LastShownPoint)) - 10800).ToString();
                            List&lt;DataPoint&gt; LoadedPoints = LoadPointsRange(param, StartTime, EndTime).Points;
                            Boxes[index].Series.Points.InsertRange(0, LoadedPoints);
                        }
                        if (Boxes.Count &gt; 0 &amp; index &lt; Boxes.Count)
                        {
                            var temp1 = Boxes[index].Series.Points.Where(key =&gt; key.X &gt; PMActualMinimumY &amp;&amp; key.X &lt; PMActualMaximumY);

                            if (temp1 != null &amp; temp1.Count() &gt; 0)
                            {
                                double max = temp1.Select(p =&gt; p.Y).Max();
                                double min = temp1.Select(p =&gt; p.Y).Min();
                                Boxes.Where(k =&gt; k.id == param).First().PlotModel.Axes[1].Reset();
                                Boxes.Where(k =&gt; k.id == param).First().PlotModel.Axes[1].Zoom(min, max);
                            }
                        }
                    }
                }
            }
        }
    }


This function calls something like:

                UpdateHistoryAsyc UHA = new UpdateHistoryAsyc(UpdateHistoryAndReSizeWhenDrag);
            IAsyncResult result = UHA.BeginInvoke(item, CurrentDuration, null, null);


Where boxes looks like:

        private ObservableCollection&lt;BoxStruct&gt; boxes;
    public ObservableCollection&lt;BoxStruct&gt; Boxes
    {
        get { return boxes; }
        set { boxes = value; RaisePropertyChanged("Boxes"); }
    }


How can I improve this LINQ code?
You don't follow capitalization conventions: ChartLastPoint, LastShownPoint, PMActualMinimumY, PMActualMaximumY, StartTime, EndTime, LoadedPoints should all be camelCase.

I suspect Lock must be camelCase as well, since I doubt it is a public property.



Use proper variable names, not temp or temp1. Same problem with param: it doesn't tell me anything, only through the code I know it's some kind of ID. 



Your code suffers from the Arrow anti-pattern. You can easily reduce some of the nesting by returning earlier:

private void UpdateHistoryAndReSizeWhenDrag(string param, long duration)
{
    lock (Lock)
    {
        if (Boxes.Count() &lt; 1)
        {
            return;
        }

        BoxStruct temp = Boxes.Where(key =&gt; key.id == param).FirstOrDefault();
        if (temp == null)
        {
            return;
        }

        int index = Boxes.IndexOf(Boxes.Where(key =&gt; key.id == param).First());
        if (index &lt; 0)
        {
            return;
        }

        /* rest of your code */
    }
}




I don't know what Boxes is, but I suspect an ICollection&lt;T&gt; or an IList&lt;T&gt; of sorts, so why then use Boxes.Count() when you can use Boxes.Count (as you do later on in your code)?



I don't see why you're using Boxes[index], since the temp contains the BoxStruct you need to work with. Later on again you do Boxes.Where(k =&gt; k.id == param).First() twice, even though you could simply use temp.

I also don't see the point of this check: if (Boxes.Count &gt; 0 &amp; index &lt; Boxes.Count): the second part is always true, and the first part you checked right at the start of your code: if (Boxes.Count() &gt; 0).

I find it a bit odd that you carefully check that Boxes contains a value you can work with, but then never check if that object's Series isn't null, and if Series's Points isn't null etc. Also, you don't do anything if you can't find an appropriate BoxStruct -- shouldn't you inform the user?



I see the magic number 10800 appear twice. This should be stored in a constant and have a descriptive name.



Why do you retrieve the same value twice, yet store it in different variables?

    double LastShownPoint = (from x in Boxes where x.id == param select x.PlotModel.Axes[0].ActualMinimum).Min();
    double PMActualMinimumY = (from x in Boxes where x.id == param select x.PlotModel.Axes[0].ActualMinimum).Min();


Moreover, since you need to use the result of from x in Boxes where x.id == param select x.PlotModel.Axes[0] three times, store it in a variable and use that variable.



PMActualMinimumY and PMActualMaximumY both end in Y, yet you compare them to a value named X.



I'm a bit worried to see a method named LoadPointsRange which seemingly returns some kind of object, from which you then take its property Points.