2012-02-10 15 views
1

この例を考えてみましょう:ユーザーがボタンをクリックすると 、ClassA急速に火災OnUserInteractionイベント10回。 ClassBがこのイベントに添付され、イベントハンドラで発生しますClassCのレンダリングメソッド。 Renderメソッドでは、AxisAngleRotation3Dが実行されますが、すべてのアニメーションは1秒間続きます。実装スレッドキュー

このシナリオでは、すべてのアニメーションがほぼ同時に実行されますが、私はそれらを順番に実行したいと思います。私はスレッドを理解するので、おそらくClassBにスレッドキューを実装する必要があります。CompletedイベントのAxisAngleRotation3Dは、次のイベントが発生することを通知します...?

これは正しいですか?これをどのように達成できますか?

答えて

3

タスクキューがあります。簡単に言えば、ConcurrentQueue<Func<bool>>フィールドなどを持ち、必要に応じてタスクを追加します。次に、タスク実行スレッドのポップアップFunc<bool>をキューから外して呼び出します。彼らが真実に戻ったら、彼らは終わった。 falseを返した場合は、その時点で完了できなかったキューにキューを追加します。私は'ClassB'で、このタイプのオブジェクトをインスタンス化します

using System; 
using System.Collections.Concurrent; 
using System.Threading; 

namespace Example 
{ 
    public class TaskScheduler : IDisposable 
    { 
     public const int IDLE_DELAY = 100; 

     private ConcurrentQueue<Func<bool>> PendingTasks; 
     private Thread ExecuterThread; 
     private volatile bool _IsDisposed; 

     public bool IsDisposed 
     { 
      get { return _IsDisposed; } 
     } 

     public void EnqueueTask(Func<bool> task) 
     { 
      PendingTasks.Enqueue(task); 
     } 

     public void Start() 
     { 
      CheckDisposed(); 

      if (ExecuterThread != null) 
      { 
       throw new InvalidOperationException("The task scheduler is alreader running."); 
      } 

      ExecuterThread = new Thread(Run); 
      ExecuterThread.IsBackground = true; 
      ExecuterThread.Start(); 
     } 

     private void CheckDisposed() 
     { 
      if (_IsDisposed) 
      { 
       throw new ObjectDisposedException("TaskScheduler"); 
      } 
     } 

     private void Run() 
     { 
      while (!_IsDisposed) 
      { 
       if (PendingTasks.IsEmpty) 
       { 
        Thread.Sleep(IDLE_DELAY); 
        continue; 
       } 

       Func<bool> task; 
       while (!PendingTasks.TryDequeue(out task)) 
       { 
        Thread.Sleep(0); 
       } 

       if (!task.Invoke()) 
       { 
        PendingTasks.Enqueue(task); 
       } 
      } 
     } 

     public void Dispose() 
     { 
      CheckDisposed(); 
      _IsDisposed = true; 
     } 
    } 
} 
+0

:ここ

は例ですか?私が何を意味しているか知っているなら、それはいつも動いていますか? – sventevit

+0

これをすべて監視しているオブジェクト(フォームなど)でインスタンス化します。それは処分されるまで実行されます。私はおそらくそれを修正する必要があります。 – Zenexer

+0

アイドル時に新しいタスクが100ミリ秒ごとに確認されます。 – Zenexer

3

ClassBはイベントをキューに追加し、一度に1つずつレンダリングすることができます(キューから読み込むためにタイマーを使用する可能性があります)。