3

私が現在取り組んでいるソフトウェアプロジェクトを参照してください。

基本的にタイマーでキャンバスを移動する以下のメソッドがあります。

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

もちろん、これらのアニメーションを次々と発生させたいのですが、2 番目のメソッド (この場合は) が呼び出されたときに のdt.Tickイベント ハンドラーが上書きされているため、2 番目のメソッドのみが実行されます。したほうがいい。DispatchTimerTurnLeft(90)

dtメソッドをそのキューにプッシュおよびポップして、 (DispatchTimerタイマーが)それらを1つずつ実行できるようにするある種のキューを作成する必要があります...「キュー」にある順序で

これを行う方法はありますか?私はここで正しい軌道に乗っていますか、それとも完全にコースから外れていますか?

4

2 に答える 2

1

DispatcherでInvoke()またはBeginInvoke()を呼び出すと、Dispatcherに関連付けられたスレッドが解放されたときに、操作がキューに入れられて実行されます。したがって、Tickイベントを使用する代わりに、Timespanを必要とするDispatcher.Invokeのオーバーロードを使用します。

于 2009-02-08T07:01:46.167 に答える
1

私は自分でこの問題を解決しました。私がしたことはQueue、タイプのグローバルを作成しDelegate、メソッドを直接実行する代わりに、それらをこのキューに追加することでした。

次に、メソッドを1つずつデキューして実行するコンストラクターに別のスレッドを作成します。

    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();
        });
    }
于 2009-02-10T05:33:50.233 に答える