Is it always bad to use Thread.Sleep()?

后端 未结 5 1251
天命终不由人
天命终不由人 2021-01-01 08:59

I created an extension method for the the class Random which executes an Action (void delegate) at random times:

public static clas         


        
5条回答
  •  鱼传尺愫
    2021-01-01 09:47

    One reason I would use Task.Delay over Thread.Sleep is the fact that you can pass a CancellationToken to it. If the user wants to StopExecutor and the random received a long duration span, you'll end up blocking for a long time. On the other hand, in Task.Delay, you can cancel the operation and it will be notified of that cancellation.

    I think there are other problems with the design you choose to make. The Random class isn't really fit to be a task scheduler. I would find it a bit odd to find a ExecuteRandomAsync, since it mostly doesn't execute a random, but execute some arbitrary Action every X minutes.

    I would instead, go about this another way. While keeping most of the internals you've already created, but putting them in a different class.

    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();
            }
        }
    }
    

提交回复
热议问题