Valores aleatorios seguros para hilos en C# – Una inmersión profunda con Tim Corey
Generar números aleatorios es una de esas tareas que todo desarrollador encuentra. Aunque crear un valor aleatorio simple pueda parecer trivial, asegurar la seguridad de hilos en C#, especialmente en entornos multihilos, puede ser complicado. En su video "Valores Aleatorios Seguros para Hilos Fáciles en C#", Tim Corey explora cómo funcionan los números aleatorios en C#, las trampas de los métodos anteriores, y cómo lograr la seguridad de hilos cuando se trabaja con múltiples hilos.
En este artículo, seguiremos la explicación de Tim, proporcionando una mirada detallada a la generación de números aleatorios seguros para hilos, mejores prácticas y técnicas de sincronización relacionadas.
Introduction to Random Values and Thread Safety in C
Tim comienza señalando que generar valores aleatorios en C# generalmente es sencillo. Sin embargo, hay diferentes maneras de hacer las cosas, y la elección depende de si tu código se ejecutará en un hilo o en múltiples hilos concurrentemente. Tim enfatiza que este video está diseñado como una guía práctica rápida para desarrolladores, ofreciendo tanto ejemplos simples como perspectivas más profundas sobre la seguridad de hilos.
Demuestra sus ejemplos en una aplicación de consola utilizando la vista previa de Visual Studio 2026 con .NET 10, pero asegura a los espectadores que el mismo código funciona en Visual Studio 2022 y .NET 9. Para aquellos que quieren seguir, Tim proporciona el código fuente en la descripción.
Traditional Random Number Generation in C
Tim comienza mostrando el enfoque clásico para generar números aleatorios usando la clase Random. Crea dos instancias, RNG1 y RNG2, y demuestra la generación de enteros aleatorios con Next().
Random rng1 = new();
Random rng2 = new();
for(int i = 0; i < 10; yo++)
{
int output1 = rng1.Next(1, 101);
int output2 = rng2.Next(1, 101);
Console.WriteLine($"Random 1: {output1}, Random 2: {output2}");
}
Tim explica que ejecutar este código produce números diferentes para cada instancia, pero este código no es seguro para hilos. En un entorno multihilos, si dos hilos acceden a la misma instancia de Random, puedes obtener valores inesperados o duplicados, porque el estado interno del objeto Random puede ser accedido simultáneamente.
Señala que una forma de garantizar la seguridad de hilos es usar una instancia de Random por hilo. Esto es importante para hilos de trabajo, métodos asincrónicos o cualquier situación en la que múltiples hilos puedan estar ejecutando código simultáneamente. Compartir la misma instancia a través de hilos sin la sincronización adecuada puede llevar a condiciones de carrera, valores incorrectos o incluso bloqueos si no se maneja adecuadamente.
Usar una Semilla para Números Aleatorios Predecibles
Tim luego demuestra el uso de una semilla. Una semilla es un valor inicial que determina la secuencia de números generados. Por ejemplo, usando una semilla de 25 tanto para RNG1 como para RNG2:
Random rng1 = new(25);
Random rng2 = new(25);
Ambas instancias producen la misma secuencia de números. Tim enfatiza que esto es una característica, no un error, y es útil para escenarios donde se requiere reproducibilidad. Esto puede ayudar en pruebas unitarias o depuración de un programa multihilos donde necesitas reproducir una secuencia de valores aleatorios a través de dos o más hilos.
Números Aleatorios Seguros para Hilos con Random.Shared
Tim introduce Random.Shared, una manera moderna y segura para hilos de generar números aleatorios. A diferencia de crear instancias manualmente, Random.Shared es un recurso compartido estático que maneja el acceso concurrente automáticamente:
int output1 = Random.Shared.Next();
int output2 = Random.Shared.Next();
Con este enfoque, no necesitas preocuparte por bloqueos, constructores estáticos o recursos compartidos. Las colecciones seguras para hilos integradas en .NET y la instancia Random.Shared hacen que sea seguro usar múltiples hilos simultáneamente.
Ventajas de Random.Shared
Tim explica varios beneficios de este enfoque:
-
No es Necesario Instanciar: No necesitas instancias separadas para cada hilo.
-
Seguro para Hilos por Defecto: Seguro para usar en tareas paralelas o hilos de trabajo.
- API Simple: Soporta enteros, decimales e incluso barajado de arreglos.
Menciona una limitación: no puedes establecer una semilla, lo que significa que las secuencias no son predecibles. Para escenarios donde se necesita el mismo orden de números en múltiples ejecuciones, aún debes usar instancias individuales con una semilla.
Garantizando Seguridad de Hilos en Código Complejo
Aunque Random.Shared maneja internamente la seguridad de hilos, los ejemplos de Tim nos permiten discutir técnicas generales de seguridad de hilos en C#. En código más complejo o entornos multihilos, a menudo necesitas sincronizar correctamente para evitar condiciones de carrera y asegurar la integridad de los datos. Algunas técnicas comunes incluyen:
-
Declaración Lock: Evita que múltiples hilos accedan a una sección crítica simultáneamente.
-
Miembros Estáticos y Constructores Estáticos: Pueden usarse para inicializar recursos compartidos de forma segura.
-
Colecciones Seguras para Hilos: Clases como ConcurrentQueue, ConcurrentStack y ConcurrentDictionary permiten acceso concurrente seguro.
- Exclusión mutua (Mutex/Monitor): Asegura que solo un hilo pueda ejecutar una sección de código a la vez.
Tim explica que en la mayoría de los casos para números aleatorios, Random.Shared elimina la necesidad de estas técnicas, pero en aplicaciones multihilo con recursos compartidos, estos métodos son esenciales para evitar bloqueos y valores inesperados.
Guías Prácticas de Tim Corey
Tim proporciona una guía clara para usar números aleatorios de manera segura en aplicaciones multihilo:
-
Use Random.Shared por simplicidad: Ideal cuando solo necesita un valor aleatorio y el rendimiento es importante.
-
Use instancias con semilla para reproducibilidad: Necesario al rastrear los mismos datos o depurar en entornos multihilo.
-
Evite Random en criptografía: Para la seguridad, use bibliotecas criptográficas en su lugar.
- Comprenda los conceptos básicos de seguridad de hilos: Sepa cuándo su código es accedido por múltiples hilos e implemente sincronización solo cuando sea necesario.
Él asegura a los desarrolladores que Random.Shared funciona incluso cuando millones de llamadas por milisegundo se realizan desde múltiples hilos, y maneja eficientemente el acceso concurrente.
Conclusion: Safe and Simple Random Numbers in C
El video de Tim Corey demuestra que generar números aleatorios seguros para hilos en C# es más fácil de lo que muchos desarrolladores creen. Usando Random.Shared, puede evitar muchos obstáculos asociados con entornos multihilo. Para casos donde son necesarias secuencias predecibles, usar instancias individuales con una semilla proporciona un enfoque confiable.
Comprender la seguridad de hilos, secciones críticas y técnicas de sincronización asegura que su código permanezca correcto y tenga un buen rendimiento en aplicaciones multihilo. Siguiendo la guía de Tim, los desarrolladores pueden escribir código seguro para hilos para hilos de trabajo, métodos asincrónicos, y tareas paralelas sin preocuparse por las condiciones de carrera, bloqueos o valores inesperados.
