Functional Programming For Everyday .NET Developmentでの Jeremy Miller の優れた作業のおかげで、必要なことすべてを実行するコマンド エグゼキュータが動作しています (スレッド プールで重い処理を実行し、結果またはエラーを同期コンテキストに送り返し、さらにポストすることさえできます)。同期コンテキストに戻ります)、しかし、スレッドプールからSynchronizationContext.Sendを使用し、重い作業を行うメソッドに渡されたSynchronization.Postを使用する理由を説明できません。Func
ドキュメントを何度か読んだことがありますが、違いが何であるかについての直感を得ることができません。Send
1 つが呼び出され、もう 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));
}
});
}