2017-02-14 32 views
7

我想每秒执行一些代码。我现在使用的代码是:我可以使用Task.Delay作为计时器吗?

Task.Run((Action)ExecuteSomething);

而且ExecuteSomething()定义如下:

private void ExecuteSomething() 
     { 
      Task.Delay(1000).ContinueWith(
       t => 
       { 
        //Do something. 

        ExecuteSomething(); 
       }); 
     } 

这是否方法阻塞线程?或者我应该在C#中使用Timer类?它似乎Timer also dedicates a separate thread for execution(?)

+1

关于“单独线程”,只有一个线程在所有定时器之间共享。 –

回答

5

微软的反应框架是非常理想的。只需NuGet“System.Reactive”即可获取该位。那么你可以这样做:

IDisposable subscription = 
    Observable 
     .Interval(TimeSpan.FromSeconds(1.0)) 
     .Subscribe(x => execute()); 

当你想停止订阅只需拨打subscription.Dispose()。除此之外,Reactive Framework可以提供比任务或基本计时器更多的功能。

+1

在我的情况下使用Rx比使用Task.Delay有什么特别的优点吗?只是想知道为了这个目的包装包装是否值得。无论如何Upvoted。 – Sharun

+0

@Sharun - Rx拥有和LINQ一样强大的功能,然后还有一些功能。根据你所描述的,没有什么你需要的,但我怀疑你实际上会从Rx提供的东西中受益。你能更详细地描述你想要做什么吗? – Enigmativity

9

Task.Delay使用Timer内部

随着Task.Delay你可以让你的代码一点点,更清晰的出价然后用Timer。并且使用async-await不会阻止当前线程(UI通常)。

public async Task ExecuteEverySecond(Action execute) 
{ 
    while(true) 
    { 
     execute(); 
     await Task.Delay(1000); 
    } 
} 

从源代码:Task.Delay

// on line 5893 
// ... and create our timer and make sure that it stays rooted. 
if (millisecondsDelay != Timeout.Infinite) // no need to create the timer if it's an infinite timeout 
{ 
    promise.Timer = new Timer(state => ((DelayPromise)state).Complete(), promise, millisecondsDelay, Timeout.Infinite); 
    promise.Timer.KeepRootedWhileScheduled(); 
} 

// ... 
相关问题