threading thread net for book c# multithreading threadpool conceptual synchronizationcontext

c# - thread - ¿Cuál es la diferencia entre SynchronizationContext.Send y SynchronizationContext.Post?



for thread c# (1)

Enviar - síncrono: esperar respuesta (o acción completada)

Post asíncrono: dejar y continuar.

Entonces tu ejemplo usa los métodos correctos en los momentos correctos. No es necesario detener el ciclo for hasta que se complete la actualización del progreso (al contrario).
Y Ejecutar desea esperar a que se complete la Acción, de lo contrario, el manejo de excepciones no tiene ningún propósito.

Gracias al buen trabajo de Jeremy Miller en Programación Funcional para el Desarrollo de .NET de todos los días , tengo un ejecutor de comandos en funcionamiento que hace todo lo que quiero (hacer un trabajo pesado en el grupo de subprocesos, enviar resultados o errores al contexto de sincronización e incluso publicar vuelva al contexto de sincronización), pero no puedo explicar por qué usa SynchronizationContext.Send del grupo de subprocesos y Synchronization.Post del Func pasó al método que hace el trabajo pesado. He leído la documentación varias veces, pero no puedo entender la diferencia. ¿Qué se supone que debo obtener del hecho de que uno se llama Send y el otro se llama Post ? Siento que la magia está en el hecho de que Send "inicia una solicitud sincrónica " y Post "inicia una solicitud asíncrona ", pero ambas solicitudes provienen del grupo de subprocesos y deben enviarse / enviarse nuevamente al subproceso de la interfaz de usuario.

¿Alguien puede explicar la diferencia, incluso si es solo un dispositivo mnemotécnico que me permite saber cuándo elegir uno sobre el otro?

En caso de que importe, este es mi código de prueba en el que utilizo Post para enviar el progreso 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); }

El método _ExecuteCommand se pasa como el siguiente parámetro de command , principalmente del artículo original, que usa Send para enviar el mensaje de error y finalización 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)); } }); }