小编典典

是否有基于任务的System.Threading.Timer替代品?

c#

我是.Net 4.0任务的新手,但是我找不到我认为是基于任务的计时器的替代品或计时器的实现,例如周期性的任务。有这样的事吗?

更新
我提出了我认为是我需要的解决方案,该解决方案是将“计时器”功能包装在带有子任务的Task内,并全部利用CancellationToken并返回Task以便能够参与进一步的Task步骤。

public static Task StartPeriodicTask(Action action, int intervalInMilliseconds, int delayInMilliseconds, CancellationToken cancelToken)
{ 
    Action wrapperAction = () =>
    {
        if (cancelToken.IsCancellationRequested) { return; }

        action();
    };

    Action mainAction = () =>
    {
        TaskCreationOptions attachedToParent = TaskCreationOptions.AttachedToParent;

        if (cancelToken.IsCancellationRequested) { return; }

        if (delayInMilliseconds > 0)
            Thread.Sleep(delayInMilliseconds);

        while (true)
        {
            if (cancelToken.IsCancellationRequested) { break; }

            Task.Factory.StartNew(wrapperAction, cancelToken, attachedToParent, TaskScheduler.Current);

            if (cancelToken.IsCancellationRequested || intervalInMilliseconds == Timeout.Infinite) { break; }

            Thread.Sleep(intervalInMilliseconds);
        }
    };

    return Task.Factory.StartNew(mainAction, cancelToken);
}

阅读 326

收藏
2020-05-19

共1个答案

小编典典

它取决于4.5,但这有效。

public class PeriodicTask
{
    public static async Task Run(Action action, TimeSpan period, CancellationToken cancellationToken)
    {
        while(!cancellationToken.IsCancellationRequested)
        {
            await Task.Delay(period, cancellationToken);

            if (!cancellationToken.IsCancellationRequested)
                action();
        }
     }

     public static Task Run(Action action, TimeSpan period)
     { 
         return Run(action, period, CancellationToken.None);
     }
}

显然,您可以添加一个也带有参数的通用版本。这实际上与其他建议的方法类似,因为在Task.Inde的内部,Delay使用计时器到期作为任务完成源。

2020-05-19