2017-02-14 19 views
7

Tôi muốn thực thi một số mã trên mỗi giây. Mã tôi đang sử dụng bây giờ là:Tôi có thể sử dụng Task.Delay làm hẹn giờ không?

Task.Run ((Hành động) ExecuteSomething);

ExecuteSomething() được định nghĩa như sau:

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

        ExecuteSomething(); 
       }); 
     } 

Liệu phương pháp này chặn một sợi? Hoặc tôi nên sử dụng lớp học Timer trong C#? Và có vẻ như Timer also dedicates a separate thread for execution (?)

+1

Về "chuỗi riêng biệt", chỉ có một chuỗi được chia sẻ giữa tất cả các bộ hẹn giờ. –

Trả lời

5

Khung phản ứng của Microsoft là lý tưởng cho việc này. Chỉ cần NuGet "System.Reactive" để lấy các bit. Sau đó, bạn có thể thực hiện việc này:

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

Khi bạn muốn ngừng đăng ký, chỉ cần gọi subscription.Dispose(). Trên hết khung phản ứng này có thể cung cấp nhiều quyền lực hơn nhiều so với Task hoặc Timers cơ bản.

+1

Việc sử dụng Rx trong trường hợp của tôi có bất kỳ lợi thế cụ thể nào không khi sử dụng Task.Delay? Chỉ muốn biết là nó có giá trị bao gồm các gói chỉ dành cho mục đích này. Upvoted anyway. – Sharun

+0

@Sharun - Rx có nhiều quyền lực như LINQ và sau đó một số. Từ những gì bạn đã mô tả không có gì nhiều hơn mà bạn cần, nhưng tôi nghi ngờ bạn thực sự sẽ được hưởng lợi từ những gì Rx cung cấp. Bạn có thể mô tả thêm về những gì bạn đang cố gắng làm không? – Enigmativity

9

Task.Delay sử dụng Timer nội

Với Task.Delay bạn có thể làm cho mã của bạn một chút-thầu rõ ràng hơn sau đó với Timer. Và việc sử dụng async-await sẽ không chặn luồng hiện tại (UI thường).

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

Từ mã nguồn: 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(); 
} 

// ... 
Các vấn đề liên quan