2010-08-05 31 views
5

Aprender a enhebrar es fascinante, sin duda, y hay algunos recursos realmente buenos para hacerlo. Pero, mi pregunta es el uso de subprocesos explícitamente como parte del diseño o desarrollo en aplicaciones del mundo real.C# Threading en aplicaciones del mundo real

He trabajado en algunas aplicaciones de .NET ampliamente utilizadas y bien diseñadas en C#, pero no encontré rastros de uso explícito. ¿No existe una necesidad real debido a que esto está siendo gestionado por CLR o hay alguna razón específica?

Además, cualquier ejemplo de threading codificado en aplicaciones .NET ampliamente utilizadas. en Codelplex o Gooogle Code también son bienvenidos.

Respuesta

3

Eso depende completamente de la aplicación.

Para un cliente aplicación que alguna vez tiene que hacer un trabajo importante (o realizar otras tareas potencialmente de larga ejecución, como hacer llamadas al servicio web) esperaría que se utilizaran hilos de fondo. Esto se puede lograr a través del BackgroundWorker, el uso explícito del grupo de subprocesos, el uso explícito de extensiones paralelas o la creación de nuevos subprocesos explícitamente.

Es menos probable que los servicios web y las aplicaciones web creen sus propios hilos, según mi experiencia. Es más probable que trate de manera efectiva cada solicitud como si tuviera un hilo separado (incluso si ASP.NET lo mueve internamente) y realice todo sincrónicamente. Por supuesto, son aplicaciones web que se ejecutan de forma asincrónica o inician conversaciones por otros motivos, pero yo diría que esto aparece con menos frecuencia que en las aplicaciones cliente.

+0

Cualquier ejemplo de tal aplicación de cliente ampliamente utilizada. de Codeplex o Código? – GilliVilla

+0

@GilliVilla: No es que yo sepa de improviso. Pero busque las aplicaciones del cliente y es probable que usen hilos en algún lugar ... –

+0

Para realizar un seguimiento: las aplicaciones del cliente también pueden usar las extensiones reactivas (que está a punto de completarse). Además, cuando Jon habla sobre aplicaciones web que tratan "cada solicitud como (* sic: has *) con un hilo separado", eso también incluye páginas asíncronas. –

5

El lugar más simple para usar el enhebrado es realizar una operación larga en una GUI mientras se mantiene la IU receptiva.

Si realiza la operación en el subproceso de interfaz de usuario, toda la GUI se congelará hasta que finalice. (Debido a que no ejecutará un bucle de mensaje)
Al ejecutarlo en una cadena de fondo, la IU seguirá siendo receptiva.

La clase BackgroundWorker es muy útil aquí.

+0

Exactamente, utilizo mucho los subprocesos para barras de progreso o cálculos pesados ​​para que la GUI no se congele y no responda. – Jage

4

está roscado aplicado explícitamente como parte del diseño o desarrollo en aplicaciones reales.

Con el fin de aprovechar al máximo los modernos sistemas multi-núcleo, el roscado debe ser parte del diseño desde el principio. Aunque es bastante fácil (especialmente en .NET 4) encontrar pequeñas porciones de código para enhebrar, para obtener una escalabilidad real, debe diseñar sus algoritmos para manejar el enhebrado, preferiblemente en un "alto nivel" en su código. Cuanto antes esto se haga en las fases de diseño, más fácil será construir apropiadamente el hilo en una aplicación.

¿No hay una necesidad real debido a que esto está siendo gestionado por CLR o hay alguna razón específica?

Definitivamente hay una necesidad. El enhebrado no es gratis, debe ser agregado por el desarrollador. La razón principal por la que esto no se encuentra con mucha frecuencia, especialmente en código fuente abierto, es realmente más una cuestión de dificultad. Incluso el uso de .NET 4, el diseño adecuado de algoritmos para enhebrar de una manera escalable y segura es difícil.

+0

+1 Enhebrar definitivamente tiene que ser parte del diseño !!!! ¡Sin dudas sobre [email protected] Entonces, ¿significa que es prescindible debido a la dificultad? La razón por la que me atasco es incluso en aplicaciones que no son de código abierto. que son críticos para la misión Se evita el enhebrado. –

+0

@Shankar: Personalmente, no creo que sea "prescindible" en absoluto: el desarrollo moderno realmente debería usar subprocesos cuando sea apropiado, y es muy apropiado para (porciones de) casi todas las aplicaciones del lado del cliente. Dicho esto, a menudo se deja fuera debido a la dificultad, incluso cuando no debería ser ... Enhebrar aumenta el costo de mantenimiento de una aplicación, pero es realmente necesario para la usabilidad. –

1

La mayoría de los usos del mundo real de roscar que he visto es simplemente para evitar el bloqueo: IU, red, llamadas a bases de datos, etc.

Usted puede verlo en su uso como BeginXXX y EndXXX pares de métodos, delegate.BeginInvoke llamadas, llamadas Control.Invoke.

Algunos sistemas que he visto, donde el uso de hilos sería una bendición, utilizan el principio de aislamiento para lograr múltiples "hilos", es decir, dividen el trabajo en fragmentos completamente no relacionados y los procesan independientemente el uno del otro - "multi-threading" (o utilización de muchos núcleos) se logra automágicamente simplemente ejecutando todos los procesos a la vez.

Creo que es justo decir que se encuentran muchas aplicaciones de stock-and-trade (presentación de datos) que en gran parte no requieren paralización masiva, ni siempre se pueden diseñar para que sean adecuadas. Los ejemplos que he visto son todos problemas muy específicos. Esto puede atribuirse a por qué no has visto implementaciones notorias de él.

0

El subprocesamiento se utiliza en todo tipo de escenarios, cualquier cosa basada en red depende del subprocesamiento, ya sea explícito (sockets stuff) o implícito (servicios web). Threading mantiene la IU receptiva. Y los servicios de Windows que tienen múltiples ejecuciones paralelas hacen lo mismo al procesar los datos, trabajando a través de colas que deben procesarse.

Esos son los más comunes que he visto.

0

La mayoría de las respuestas hacen referencia a tareas de larga ejecución en una aplicación de GUI. Otro escenario de uso muy común en mi experiencia son las colas Producer/Consumer. Tenemos muchas aplicaciones de utilidad que tienen que realizar solicitudes web, etc. a menudo a una gran cantidad de puntos finales. Usamos el patrón de subprocesamiento productor/consumidor (generalmente integrando un grupo de subprocesos personalizado) para permitir una paralelización alta de estas tareas.

De hecho, en este momento estoy revisando una aplicación que carga un archivo de 200MB a 200 ubicaciones FTP diferentes. Usamos SmartThreadPool y ejecutamos aproximadamente 50 cargas en paralelo, lo que permite que todo el lote se complete en menos de una hora (en lugar de más de 50 horas si todas las cargas se realizaran consecutivamente, por lo que en nuestro uso encontramos mejoras lineales casi directas en hora).

0

Como programadores de hoy en día nos gusta abstracciones por lo que utilizar hilos llamando a los métodos asincrónicos o BeginInvoke y usando cosas como BackgroundWorker o PFX en .Net 4.

Sin embargo, a veces hay una necesidad de hacer la rosca a sí mismo. Por ejemplo, en una aplicación web que construí tengo una cola de correo que agregué desde dentro de la aplicación y hay un hilo de fondo que envía los correos electrónicos. Si el hilo advierte que la cola se está llenando más rápido de lo que lo está enviando crea otro hilo si luego ve que ese hilo está inactivo, lo mata. Esto se puede hacer con una abstracción de nivel superior, supongo, pero lo hice manualmente.

2

Definitivamente un +1 en las Extensiones Paralelas a .NET. Microsoft ha hecho un gran trabajo aquí para mejorar ThreadPool. Solía ​​tener una cola global que manejaba todas las tareas, incluso si se generaban a partir de un hilo de trabajo. Ahora tienen una cola global sin bloqueos y colas locales para cada subproceso de trabajo. Esa es una mejora muy agradable.

No soy tan fanático de cosas como Parallel.For, Parallel.Foreach y Parallel.Invoke (regions), ya que creo que deberían ser extensiones de lenguaje puro en lugar de bibliotecas de clases. Obviamente, entiendo por qué tenemos este paso intermedio, pero es inevitable que C# gane mejoras de idioma para la concurrencia y es igualmente inevitable que tengamos que volver y cambiar nuestro código para aprovecharlo :-)

En general, si busca construir aplicaciones concurrentes en .NET, se debe a usted mismo para investigar las extensiones paralelas.También creo que, dado que este es un esfuerzo bastante incipiente de Microsoft, debería ser muy elocuente sobre lo que funciona para usted y lo que no funciona, independientemente de lo que perciba que es su propio nivel de competencia con la concurrencia. Microsoft definitivamente está escuchando, pero no creo que haya tantas personas que usan las Extensiones Paralelas. Ayer estuve en VSLive Redmond y vi una sesión sobre este tema y continúo impresionado con el equipo que está trabajando en esto.

Divulgación: solía ser el director de marketing de Visual Studio y ahora estoy en una startup llamada Corensic donde estamos creando herramientas para detectar errores en aplicaciones concurrentes.

1

La cuestión de si hacer uso de una implementación de subprocesamiento explícita es normalmente una consideración de diseño como otros han mencionado aquí. Tratar de implementar la concurrencia como una ocurrencia tardía generalmente requiere muchos cambios radicales y mayoristas.

Tenga en cuenta que simplemente lanzar subprocesos en una aplicación no aumenta el rendimiento o la velocidad de forma inherente, dado que hay un costo en la gestión de cada subproceso, y tal vez un poco de carga de memoria (sin mencionar, la depuración puede ser divertida)

Desde mi experiencia, el lugar más común para implementar un diseño de subprocesos ha sido en Servicios de Windows (aplicaciones en segundo plano) y en aplicaciones que tienen escenarios de casos de uso donde un volumen de trabajo se puede dividir fácilmente en parcelas de trabajo más pequeñas (y entregado a los hilos para completar de forma asincrónica).

En cuanto a los ejemplos, se puede consultar la Microsoft Robotics Studio (por lo que yo sé que hay una free version ahora) - se trata con un redistribuible (no puedo encontrar como una descarga independiente) de la Concurrency and Coordination Runtime, hay algo de cobertura de ella en Microsoft Channel 9.

Como han mencionado otros, el equipo de Extensiones Paralelas (blog is here) ha realizado un gran trabajo con seguridad de hilos y ejecución paralela y puede encontrar ejemplos/ejemplos en el MSDN Code site.

0

No puedo resistir el caso límite: en algunas aplicaciones donde se debe alcanzar un alto grado de seguridad operativa o se debe tolerar un alto grado de incertidumbre operativa, los hilos y procesos se consideran desde el diseño inicial de la arquitectura. paso a través de la entrega final

Caso 1: para sistemas que deben alcanzar niveles extremadamente altos de confiabilidad operacional, se pueden usar tres subsistemas completamente separados utilizando tres mecanismos diferentes en una arquitectura de votación: engendrar 3 hilos/procesos en cada uno de los votantes, esperar a que concluyan/mueran/mueran, y proceden IFF todos dicen lo mismo - ejemplo - complejos de aviónica complejos

Caso 2: para sistemas que tienen que lidiar con un alto grado de incertidumbre operacional: haga lo mismo, pero una vez que algo/algo le devuelve, mate a los rezagados y continúe con la mejor respuesta que recibió - ejemplo - complejo algoritmos de negociación intradía que intentan destruir el negocio que los emplea :-)

Cuestiones relacionadas