visual tiempo threading thread studio net c# multithreading sleep

c# - tiempo - vb net thread sleep 1000



¿Siempre es malo usar Thread.Sleep()? (5)

Creé un método de extensión para la clase Random que ejecuta una Action (delegado void) en momentos aleatorios:

public static class RandomExtension { private static bool _isAlive; private static Task _executer; public static void ExecuteRandomAsync(this Random random, int min, int max, int minDuration, Action action) { Task outerTask = Task.Factory.StartNew(() => { _isAlive = true; _executer = Task.Factory.StartNew(() => { ExecuteRandom(min, max, action); }); Thread.Sleep(minDuration); StopExecuter(); }); } private static void StopExecuter() { _isAlive = false; _executer.Wait(); _executer.Dispose(); _executer = null; } private static void ExecuteRandom(int min, int max, Action action) { Random random = new Random(); while (_isAlive) { Thread.Sleep(random.Next(min, max)); action(); } } }

Funciona bien.

Pero, ¿está bien el uso de Thread.Sleep() en este ejemplo o, en general, nunca debes usar Thread.Sleep() ¿Qué complicaciones podrían ocurrir? ¿Hay alternativas?


¿Está usando Thread.Sleep bad? Generalmente no, si realmente quieres suspender el hilo . Pero en este caso no desea suspender el hilo , desea suspender la tarea .

Entonces, en este caso, debes usar:

await Task.Delay(minDuration);

Esto no suspenderá todo el hilo, sino solo la única tarea que desee suspender. Todas las demás tareas en el mismo hilo pueden continuar ejecutándose.


Piénsalo de esta manera.

Dormir un hilo es peligroso porque más de una vez, más de una tarea depende de ese hilo, sin mencionar los componentes clave del programa. Nunca es apropiado usar sleep on threads, querrá usarlos cuando sean beneficiosos para su programa.

A muchas personas se les enseña a no dormir debido a un comportamiento impredecible. Es como manejar un equipo, eventualmente vas a tener que dejar ir a almorzar a algunos y mientras el resto esté funcionando mientras que los que elegiste ir a almorzar están fuera, entonces deberías estar bien y ser capaz de trabajar aún .

Simplemente no envíe personas a almorzar si hay personas en el proyecto que dependen de su presencia.


Una razón por la que usaría Task.Delay over Thread.Sleep es el hecho de que puede pasarle un CancellationToken . Si el usuario quiere StopExecutor y el azar recibió un lapso de larga duración, terminará bloqueando por un tiempo prolongado. Por otro lado, en Task.Delay , puede cancelar la operación y se le notificará dicha cancelación.

Creo que hay otros problemas con el diseño que eliges hacer. La clase Random no es realmente adecuada para ser un programador de tareas. Me resultaría un poco extraño encontrar ExecuteRandomAsync , ya que en su mayoría no ejecuta un azar, sino que ejecuta alguna Action arbitraria cada X minutos.

En cambio, lo haría de otra manera. Mientras conserva la mayoría de las partes internas que ya ha creado, pero las pone en una clase diferente.

public class ActionInvoker { private readonly Action _actionToInvoke; public ActionInvoker(Action actionToInvoke) { _actionToInvoke = actionToInvoke; _cancellationTokenSource = new CancellationTokenSource(); } private readonly CancellationTokenSource _cancellationTokenSource; private Task _executer; public void Start(int min, int max, int minDuration) { if (_executer != null) { return; } _executer = Task.Factory.StartNew( async () => await ExecuteRandomAsync(min, max, _actionToInvoke), _cancellationTokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default) .Unwrap(); } private void Stop() { try { _cancellationTokenSource.Cancel(); } catch (OperationCanceledException e) { // Log the cancellation. } } private async Task ExecuteRandomAsync(int min, int max, Action action) { Random random = new Random(); while (!_cancellationTokenSource.IsCancellationRequested) { await Task.Delay(random.Next(min, max), _cancellationTokenSource.Token); action(); } } }


Sleep "habla" con el sistema de operación que desea suspender el hilo. Se trata de una operación que consume muchos recursos porque su hilo usa RAM de todos modos (aunque no requiere tiempo de procesamiento).

Con el grupo de subprocesos, puede usar recursos de subprocesos (fe RAM) para procesar algunas otras tareas pequeñas. Para hacerlo, Windows le permite poner un hilo en reposo en un estado especial de alerta, por lo que puede ser despertado y utilizado temporalmente.

Así que Task.Delay te permite poner subprocesos en alertable sleep y, por lo tanto, te permite usar los recursos de estas unidades threadl, no las necesitas.


Todas las respuestas son correctas, y me gustaría agregar una vista práctica:

Cuando tiene que probar un componente remoto no en tiempo real (por ejemplo, un motor de búsqueda), necesita darle tiempo para ir a su nuevo estado antes de volver a hacer referencia a él para las afirmaciones. En otras palabras, quiere suspender su prueba por un tiempo. Dado que el rendimiento de la prueba en sí es irrelevante (distinga entre el rendimiento de la prueba y el rendimiento del componente ), a veces prefiere mantener su código (de la prueba) lo más simple y directo posible, y evitar incluso el complejidad mínima de código asíncrono. Por supuesto, podría comenzar una nueva prueba en lugar de esperar a su componente (esa es la diferencia entre await Task.Delay() y Thread.Sleep() ), pero la suposición era que no tiene prisa por eso.