Dispatcher.Invoke()中的随机计时使用

时间:2012-08-28 12:46:36

标签: wpf invoke dispatcher

首先,抱歉我的英语不好。

我必须几乎实时绘制曲线。要做到这一点,我使用: - 一个堆栈点的线程 - 一个解开积分的线程 - 以及对我来说是黑盒子的“图形线程”,我只能通过窗口调度程序通过调用方法到达它。

当我在Dispatcher.Invoke调用的开始和结束之间记录时间时,我看到的提前期为3到110ms。在有效绘图方法的开始和结束之间,我看到的交付时间从3到55毫秒?!!? 我无法理解我如何浪费这么多时间,为什么我会有如此随机的时间,而且更多的是如何让这快速和直接。(就像我使用堆栈,这些巨大的时间经常堆栈溢出,崩溃的应用程序: S)

UnStack线程循环:

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);
}

感谢您给我带来的任何帮助,或者如果您看到我错过了一些令人难以置信的事情:S。

PS:对于那些已经用法语发帖的人抱歉:p

2 个答案:

答案 0 :(得分:0)

切换线程涉及开销,它不是免费操作,可能有些不可预测。这完全取决于操作系统如何分配时间片。您必须确保您的代码足够可靠以处理此问题。

请记住:Windows不是实时操作系统。

答案 1 :(得分:0)

作为替代策略:一次绘制所有线段,然后在可见性或不透明度上为每个线段添加动画。下面的代码绘制一条虚线,一次一个段。与自己进行线程相比,动画会提供更好的计时行为。

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);
}