0

First, sorry for my bad english.

I have to draw a curve almost in real time. To do that I use: - a Thread to stack points - a thread to unstack points - and the "graphic thread" which is kind of blackbox to me, and that i just can reach it by the window Dispatcher with Invoke methode.

When i log time between start and end of the call to Dispatcher.Invoke, i see a lead time from 3 to 110ms. And between start and end of the effective drawing methode i see lead time from 3 to 55ms ?!!? I cant understand how i can waste so much time, why do i got so random timing, and more over how can i make this quick and straigh.(like i use a stack, with these huge timing the stack overflow often, crashing application :S)

UnStack thread loop:

while (exRunningFlag)
{
    lock (myLock)
    {                        
        while ( stackingListPoint.Count > 0)
        {
           LOG
           this.Dispatcher.Invoke(new Action(() =>
                    {
                        LOG                                   
                            graph.AddPoint(this.stackingListPoint.Dequeue());                                        
                        LOG
                    }), System.Windows.Threading.DispatcherPriority.Send);
                    LOG                                
            }
        }
    }                    
    Thread.Sleep(3);
}


public void AddPoint(System.Windows.Point pt)//Data
{            
    int resNeedResize = needResize(pt);   
// ------ rare case, only when need to redraw all curves. This is not relative to my weird delay
    if (resNeedResize != 0)
    {
        ReDraw(resNeedResize);
        return;
    }
// ----
    currentPt = ConversionDataPtToGraphPt(pt);
    if ((lastPt.X != -1) && (lastPt.Y != -1))
    {     
            g = CreateGraphics();                   
            g.DrawLine(pen_Courbe, lastPt, currentPt);
            g.Flush(); 
    }
    lastPt = currentPt;
    ListPointCollection.Last().Add(pt);
}

Thanks for any help u can bring to me, or if u saw that I missed something revelant:S.

PS: Sorry to people who already saw that post in french :p

H.B.
  • 166,899
  • 29
  • 327
  • 400

2 Answers2

0

There is overhead involved in switching threads, it's not a free operation and can be somewhat unpredictable. It all depends on how the operating system assigns time slices. You have to make sure your code is reliable enough to handle this.

Remember: Windows is NOT a real-time operating system.

Matt Burland
  • 44,552
  • 18
  • 99
  • 171
0

As an alternative strategy: draw all line segments at once, then add an animation per line segment on visibility or opacity. Code below draws a dashed line, one segment at a time. The animations will give better timing behaviour than doing the threading yourself.

for (int i = 0; i < 5; i++)
{
    Line l = new Line();
    l.X1 = i*50;
    l.Y1 = 50;
    l.X2 = i*50+40;
    l.Y2 = 50;
    l.Stroke = new SolidColorBrush(Colors.Black);
    l.StrokeThickness = 3;

    // All lines are drawn right away, just not visible. The animations fade them 
    // in one by one.
    l.Opacity = 0;
    DoubleAnimationUsingKeyFrames opanim = new DoubleAnimationUsingKeyFrames();
    opanim.KeyFrames.Add(new LinearDoubleKeyFrame(0 , TimeSpan.Zero));
    opanim.KeyFrames.Add(new LinearDoubleKeyFrame(0, TimeSpan.FromSeconds(i + 1)));
    opanim.KeyFrames.Add(new LinearDoubleKeyFrame(1, TimeSpan.FromSeconds(i + 2)));

    l.BeginAnimation(Line.OpacityProperty, opanim);

    MyCanvas.Children.Add(l);
}
Nzc
  • 170
  • 1
  • 5