2011-07-20 13 views
0

レガシーVB6コードでは、イベントハンドラーをブロックせずにステートマシンを実行できるように、システムタイマーを使用してコールバックを行いました。いくつかの擬コード例C#イベントドリブンステートマシンはWindows.Forms.Timerを使用してイベントライザーを解放する必要があります

Sub Unhooked(State info) 
    Select Case info 
     Case 1 
      NextState = somestate1 
     Case 2 
      NextState = somestate2 
     Case 3 
      NextState = somestate3 
    End Select 
    RunStateMachine 
End Sub 

Sub RunStateMachine() 
    MyObject.GoDoSomethingAndCallMeBack 
End Sub 

Sub MyObject_EventCallback(State info) 
    APITimer.SetUpCallBackTarget (Unhooked, info) 
    APITimer.CallMeBackInASec 
End Sub 

うまくいけば、あなたが解雇されているイベントハンドラの後半になり、いくつかのコールは、ステートマシンで作られているアイデアを取得し、それがイベントようにコールバックを行うためにタイマーを設定しますハンドラコードは、次の状態に移る前に完了できます。

私はC#で同様の静脈を続けていますが、言語がこれを行うためのより洗練された方法を提供すると確信しているので間違っています。私のC#ステートマシンはまだUIスレッド上でイベントを発生させるVB6オブジェクトを呼び出すので、ステートマシンが続行される前にリリースされるように、イベントハンドラの 'unhooking'の良い方法はありますか?

BeginInvokeを使ってステートマシンを実行するためにポンプにメッセージを追加することはできますが、スレッドプールスレッドではなく同じスレッドではフォームやコントロールではありません。私はタイマーを使用しないソリューションを思いつくことができると思うが、うまくいけば使いやすいので、どんなアイディアも素晴らしいだろう。あなたの当面の問題を解決するために

答えて

1

、あなたは例えば、UIスレッドのコンテキストにTaskをキューに入れることができ:

var ui = TaskScheduler.FromCurrentSynchronizationContext(); 
Task.Factory.StartNew(() => Unhooked(info), CancellationToken.None, 
    TaskCreationOptions.None, ui); 

UI SynchronizationContextは、あなたのオブジェクトは、フォームまたはコントロールされていなくても検出することができます。 SynchronizationContextの詳細については、my MSDN articleを参照してください。

あなたのコードで多くのことを、これを持っている場合、あなたはおそらくヘルパーメソッドにそれをラップすることをお勧めします:物事のより広範な方式で

、真剣Async CTPTask-Based Asynchronous Pattern APIの設計を考えますUIスレッド(つまりイベントベースの非同期パターン)でイベントを発生させる代わりに、

+0

ありがとう、これは私が必要としていたものです! – Akuma

関連する問題