C# continuación de primera clase a través de C++ interop o de alguna otra manera?


Tenemos una multitarea de muy alto rendimiento, casi en tiempo real aplicación C#. Este rendimiento se logró principalmente mediante la implementación de multitarea cooperativa en la empresa con un programador de producción local. Esto a menudo se llama micro-hilos. En este sistema todas las tareas se comunican con otras tareas a través de colas.

El problema específico que tenemos parece ser solucionable solo a través de continuaciones de primera clase que C# no soporta.

Específicamente el problema surge en 2 casos lidiando con las colas. Siempre que una tarea en particular realice algún trabajo antes de colocar un elemento en una cola. ¿Qué pasa si la cola está llena?

Por el contrario, una tarea diferente puede hacer algún trabajo y luego tener que quitar un elemento de una cola. ¿Y si la cola está vacía?

Hemos resuelto esto en el 90% de los casos vinculando las colas a las tareas para evitar que se invoquen tareas si alguna de sus colas de salida está llena o la cola de entrada está vacía.

Además, algunas tareas se convirtieron en estado de las máquinas para que puedan manejar si una cola está llena / vacía y continuar sin esperar.

El verdadero problema surge en unos pocos casos extremos donde no es práctico hacer ninguna de esas soluciones. La idea en ese escenario sería guardar el estado de la pila en el punto y cambiar a una tarea diferente para que pueda hacer el trabajo y posteriormente reintentar la tarea en espera cada vez que pueda continuar.

En el pasado, intentamos que la tarea en espera volviera a la programación (recursivamente) para permitir que las otras tareas vuelvan a intentar la tarea en espera. Sin embargo, eso llevó a demasiadas situaciones de "estancamiento".

Hubo un ejemplo en algún lugar de un host CLR personalizado para hacer que los subprocesos.NET realmente operen como "fibras" que esencialmente permite cambiar el estado de la pila entre subprocesos. Pero ahora no puedo encontrar ningún código de muestra para eso. Además, parece que tomará algo de complejidad significativa para hacerlo bien.

¿Alguien tiene alguna otra idea creativa cómo para cambiar entre tareas de manera eficiente y evitar los problemas anteriores?

¿Hay algún otro host CLR que ofrezca esto, comercial o de otro tipo? ¿Hay alguna biblioteca nativa adicional que pueda ofrecer alguna forma de continuaciones para C#?

Author: bobbymcr, 2011-12-31

5 answers

Existe C# 5 CTP, que realiza una transformación de estilo de paso de continuación sobre métodos declarados con la nueva palabra clave async, y llamadas basadas en paso de continuación cuando se usa la palabra clave await.

Esto no es realmente una nueva característica de CLR, sino más bien un conjunto de directivas para que el compilador realice la transformación de CPS sobre su código y un puñado de rutinas de biblioteca para manipular y programar continuaciones. Los registros de activación para los métodos async se colocan en el montón en lugar de la pila, por lo que no están vinculados a un hilo específico.

 2
Author: Jeffrey Hantin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-15 12:40:16

No, no va a funcionar. C# (e incluso IL) es un lenguaje demasiado complejo para realizar tales transformaciones (CPS) de una manera general. Lo mejor que puede obtener es lo que C # 5 ofrecerá. Dicho esto, probablemente no podrá romper/reanudar con bucles/iteraciones de orden superior, que es realmente lo que desea de las continuaciones reificables de propósito general.

 1
Author: leppie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-15 12:45:29

El modo de fibra se eliminó de la v2 del CLR debido a problemas bajo estrés, consulte:

Que yo sepa, el soporte de fibra aún no se ha vuelto a agregar, aunque de leer los artículos anteriores puede agregarse nuevamente (sin embargo, el hecho de que nada haya mencionado durante 6-7 años sobre el tema me hace creer que es poco probable).

FYI fiber support estaba destinado a ser una forma para las aplicaciones existentes que utilizan fibras (como SQL Server) para alojar el CLR de una manera que les permita maximizar el rendimiento, no como un método para permitir que las aplicaciones. Net creen cientos de hilos - en resumen, las fibras no son una solución mágica para su problema, sin embargo, si tiene una aplicación que utiliza fibras y desea alojar el CLR, entonces las API de alojamiento administrado proporcionan los medios para el CLR para "trabajar bien" con su aplicación. Una buena fuente de información sobre esto sería la documentación de la API de alojamiento administrado , o para ver cómo SQL Server aloja el CLR, del cual hay varios artículos altamente informativos.

También tome una lectura rápida de Hilos, fibras, pilas y espacio de direcciones.

 1
Author: Justin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-15 13:24:54

En realidad, decidimos una dirección para ir con esto. Estamos usando el patrón del Observador con el mensaje Passsing. Construimos una biblioteca casera para manejar toda la comunicación entre "Agentes" que son similares a un proceso Erlang. Más tarde consideraremos el uso de AppDomains para separar aún mejor a los agentes entre sí. Las ideas de diseño fueron tomadas del lenguaje de programación Erlang que tiene un procesamiento mult-core y distribuido extremadamente confiable.

 1
Author: Wayne,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-15 15:08:31

La solución a su problema es utilizar algoritmos sin bloqueos que permitan el progreso de todo el sistema de al menos una tarea. Necesita usar un ensamblador en línea que dependa de la CPU para asegurarse de que sus CAS atómicos (comparar e intercambiar). Wikipedia tiene un artículo así como patrones descritos en el libro de Douglas Schmidt llamado "Arquitectura de Software Orientada a Patrones, Patrones para Objetos Concurrentes y en Red". No está claro de inmediato para mí cómo va a hacer eso bajo el dotnet framework.

Otra forma de resolver el problema es utilizando el patrón de publicación de suscriptores o posibles grupos de subprocesos.

Espero que esto haya sido útil?

 0
Author: Damian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-31 21:22:29