2011-12-19 2 views
1

私はいつもSynchronizationContextを使って別のスレッドへの呼び出しをマーシャリングできると考えました。 SyncCtx.Send()は何もしませんが、指定されたデリゲートを呼び出す(同じスレッドにとどまります)ので、私は間違っていました。本当にSynchronizationContextから派生し、スレッドコンテキストで作業する必要がありますか?私は何かが欠けているように感じる。スレッドマーシャリングのようなフレームワーク

私がしたいこと:アプリ内でコマンドを実行するための小さなAPIを想像してみてください。また、コマンドの実行が完了したときにデリゲートを実行できるように、バックグラウンドスレッドでコマンドを実行することもできます。この "Call-me-when-done" -Delegateは、成功/失敗フラグ、オプションの例外情報などを含む単一のパラメータ(状態)を取得します。このデリゲートを元の呼び出しスレッドで呼び出して、libを使用する開発者が必要な呼び出しなどを処理する必要があります。私はちょうどこれを取り除き、単純な非スレッド対応のプログラミングをしたいと思います。 WindowsFormsSynchronizationContextは、あなたがターゲットとして何らかのコントロールを与えていない場合でも役に立ちません。

ありがとうございました!

答えて

0

winformsで同期コンテキストを使用している場合、呼び出しはGUIスレッドにマーシャリングされます。私はこのような何かが動作する必要がありますね、あなたの特定のケースのための

、おそらくCommand

public class CommandManager 
{ 
    private readonly SynchronizationContex _synchronizationContex; 

    public CommandManager(SynchronizationContext synchronizationContex) 
    { 
     _synchronizationContex = synchronizationContex; 
    } 

    public void ExecuteAsync(Func<State> action, Action<State> callback) 
    { 
     ThreadPool.QueueUserWorkItem(o => { 
              state = action(); 
              _synchronizationContex.Send(oo => callback(state)); 
              }); 
    } 
} 

を表すクラスを作成することをお勧めだろう、あなたはGUIのスレッドで(このように作成したいです、

commandManager.ExecuteAsync(() => new State() { Success = true }, 
          c => MessageBox.Show("success in the GUI thread")); 
+0

彼:そう

var commandManager = new CommandManager(SynchronizationContext.Current); 

)メインフォームで、たとえば、あなたはこのようにそれを使用したいですお返事ありがとうございましたが、実際に私がしたのと同じ間違いをしています。 SynchronizationContextは何もしません。 Sendは、Sendが呼び出されたスレッドと同じスレッドでデリゲートを呼び出します。>マーシャリングなし(リフレクタを使用) WindowsFormsSynchronizationContext f.e.マーシャリングを行いますが、指定されたターゲットコントロールでのみ行います。それはどちらも助けにならない。 – Gope

+0

@Gope 'SynchronizationContext'は、' WindowsFormsSynchronizationContext'の基本クラスです。あなたがwinformsアプリケーションにいるとき、 'SynchronizationContext.Current'は' WindowsFormsSynchronizationContext'を保持していますので、スレッドをマーシャリングします。それはマーシャルではないという結論にどのようにきたのですか? –

+0

それは面白いです!私は両方のクラスのコードを調べていました。私のコード全体がUnitTestsで動作していたので、私はSyncCtxを自分で構築し、ManagedThreadIdsをチェックしていました。基本クラスは、コードと結果のスレッドIDで分かるようにマーシャリングされません。私はWFSyncCtxのインスタンスをSC.Currentの内部に置くフレームワークは考えていませんでした...私はそれを探るつもりですが、あなたが言っていることは完璧な意味を持っています。私のテストクラスは私から隠されています。 :D ありがとう! – Gope

関連する問題