Gracias al buen trabajo de Jeremy Miller en Functional Programming For Everyday .NET Development, tengo un ejecutor de comandos que funciona y que hace todo lo que quiero (realizar trabajos pesados en el grupo de subprocesos, enviar resultados o errores al contexto de sincronización e incluso registrar el progreso en el contexto de sincronización), pero no puedo explicar por qué usa SynchronizationContext.Send del grupo de subprocesos y Synchronization.Post del Func
pasado al método que hace el trabajo pesado. He leído la documentación varias veces, pero no puedo entender lo que es la diferencia. ¿Qué se supone que obtengo del hecho de que uno se llama Send
y se llama Post
? Tengo la sensación de la magia está en el hecho de Send
"inicia una sincrónica demanda" y Post
"inicia una petición asíncrona ", pero ambas solicitudes proceden de la agrupación de hebras y necesitan ser enviados/enviados de vuelta al hilo de interfaz de usuario.¿Cuál es la diferencia entre SynchronizationContext.Send y SynchronizationContext.Post?
¿Alguien puede explicar la diferencia, incluso si se trata simplemente de un dispositivo mnemónico que me permite saber cuándo elegir uno sobre el otro?
En caso de que importa, este es mi código prueba donde uso Post
para enviar el progreso de nuevo a la interfaz de usuario:
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);
}
Eso _ExecuteCommand
método se pasa como el parámetro command
a continuación, en su mayoría de la artículo original, que utiliza para enviar Send
finalización y el mensaje de error de nuevo a la interfaz de usuario:
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));
}
});
}
Son métodos muy mal nombrados. –