2009-02-08 64 views
3

参照Software Project I am currently working onWPF:使用定时器在线程中构建队列

我有下面的方法,基本上移动帆布带定时器:

DispatcherTimer dt = new DispatcherTimer(); //global 
public void Ahead(int pix) 
    { 
      var movx = 0; 
      var movy = 0; 
      dt.Interval = TimeSpan.FromMilliseconds(5); 
      dt.Tick += new EventHandler((object sender, EventArgs e) => 
      { 
       if (movx >= pix || movy >= pix) 
       { 
        dt.Stop(); 
        return; 
       } 
       Bot.Body.RenderTransform = new TranslateTransform(movx++, movy++); 
      }); 
      dt.Start(); 
    } 
public void TurnLeft(double deg) 
    { 

     var currAngle = 0; 
     dt.Interval = TimeSpan.FromMilliseconds(5); 
     dt.Tick += new EventHandler(delegate(object sender, EventArgs e) 
     { 
      if (currAngle <= (deg - (deg * 2))) 
      { 
       dt.Stop(); 
      } 
      Bot.Body.RenderTransform = new RotateTransform(currAngle--, BodyCenter.X, BodyCenter.Y); 
     }); 
     dt.Start(); 
    } 

现在,从另一个库,这些方法被称为像这样:

public void run() 
{ 
    Ahead(200); 
    TurnLeft(90); 
} 

现在当然,我希望这些动画在另一个之后发生,但是发生的情况是当第二种方法(在这种情况下为TurnLeft(90))被调用时,DispatchTimerdt.Tick事件处理程序被覆盖,因此只有第二种方法d得到执行,因为它应该。

我需要创建某种排队方式,这样我就可以将方法推送到该队列,以便dtDispatchTimer定时器)逐个执行它们......按照它们在“队列”中的顺序执行它们,

我可以这样做吗?我在这里的正确轨道上,还是完全偏离?

回答

1

我自己解决了这个问题。我所做的是创建一个类型为Delegate的全局Queue,而不是直接执行这些方法,而是将它们添加到此队列中。

然后我会在构造一个单独的线程将出列方法逐一执行它们:

Queue<TimerDelegate> eventQueue = new Queue<TimerDelegate>(); 

    public Vehicle(IVehicle veh, Canvas arena, Dispatcher battleArenaDispatcher) 
    { 
     DispatcherTimer actionTimer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(100) }; 
     actionTimer.Tick += new EventHandler(delegate(object sender, EventArgs e) 
    { 
     if (IsActionRunning || eventQueue.Count == 0) 
     { 
      return; 
     } 
     eventQueue.Dequeue().Invoke(new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(5) }); 
    }); 
    actionTimer.Start(); 
    } 

    public void TurnRight(double deg) 
    { 
     eventQueue.Enqueue((TimerDelegate)delegate(DispatcherTimer dt) 
     { 
      IsActionRunning = true; 
      var currAngle = 0; 
      dt.Tick += new EventHandler(delegate(object sender, EventArgs e) 
      { 
       lock (threadLocker) 
       { 
        if (currAngle >= deg) 
        { 
         IsActionRunning = false; 
         dt.Stop(); 
        } 
        Rotator_Body.Angle++; 
        currAngle++; 
       } 
      }); 
      dt.Start(); 
     }); 
    } 
+1

音序器!万分感谢! – discorax 2009-10-12 17:30:50

1

当您在Dispatcher上调用Invoke()或BeginInvoke()时,操作将排队并在与Dispatcher关联的线程空闲时运行。因此,不要使用Tick事件,而要使用带TimeSpan的Dispatcher.Invoke重载。

+0

但我需要Tick事件动画的运动。 – 2009-02-08 07:16:21