31

Functional Programming For Everyday .NET Developmentでの Jeremy Miller の優れた作業のおかげで、必要なことすべてを実行するコマンド エグゼキュータが動作しています (スレッド プールで重い処理を実行し、結果またはエラーを同期コンテキストに送り返し、さらにポストすることさえできます)。同期コンテキストに戻ります)、しかし、スレッドプールからSynchronizationContext.Sendを使用し、重い作業を行うメソッドに渡されたSynchronization.Postを使用する理由を説明できません。Funcドキュメントを何度か読んだことがありますが、違いが何であるかについての直感を得ることができません。Send1 つが呼び出され、もう 1 つが呼び出されるという事実から、私は何を得るべきPostでしょうか? 私は魔法が実際にあると感じますSend同期要求を開始する」およびPost非同期要求を開始する」が、両方の要求がスレッド プールから送信され、UI スレッドに送信/ポストされる必要があります。

誰かが違いを説明できますか?それは、どちらをいつ選択するかを知らせる単なるニーモニックデバイスであっても?

重要な場合に備えて、これは進行状況を UI に戻すために使用するテスト コードです。Post

private Action _ExecuteCommand
                (SynchronizationContext context
                 , Action<int, int> progress
                 , Action<int, int> after)
{
    int count = 3;
    int accumulatedValue = 0;
    int threadId = Thread.CurrentThread.ManagedThreadId;
    for (int i = 0; i < count; i++)
    {
        Thread.Sleep(1000);
        context.Post(delegate { progress(i + 1, threadId); });
        accumulatedValue += i;
    }

    return () => after(threadId, accumulatedValue);
}

その_ExecuteCommandメソッドは、command以下のパラメーターとして渡されます。ほとんどは元の記事からのもので、Send完了メッセージとエラー メッセージを UI に送り返すために使用されます。

public void Execute(Func<Action> command, Action<Exception> error)
{
    ThreadPool.QueueUserWorkItem(o =>
     {
         try
         {
             Action continuation = command();
             _Context.Send(s => continuation());
         }
         catch (Exception e)
         {
             _Context.Send(s => error(e));
         }
     });
}
4

1 に答える 1

36

送信 - 同期: 応答を待つ (またはアクションが完了する)

ポスト - 非同期: ドロップオフして続行

したがって、あなたの例では、適切なタイミングで正しいメソッドを使用しています。進行状況の更新が完了するまで (逆に) for ループを停止する必要はありません。
そして Execute はアクションが完了するのを待ちたいと思っています。そうでなければ、例外処理には目的がありません。

于 2010-03-18T20:34:15.327 に答える