2010-11-19 50 views
12

Có cách nào để lên lịch một Tác vụ để thực hiện trong tương lai bằng cách sử dụng Thư viện song song tác vụ không?Cách lên lịch một nhiệm vụ để thực hiện trong Thư viện song song nhiệm vụ

Tôi nhận ra mình có thể làm điều này với các phương thức tiền .NET4 chẳng hạn như System.Threading.Timer ... tuy nhiên nếu có cách TPL để thực hiện điều này, tôi muốn nằm trong thiết kế của khung công tác. Tôi không thể tìm thấy một tuy nhiên.

Cảm ơn bạn.

Trả lời

2

Đặt bộ hẹn giờ một lần, khi được kích hoạt, khởi động tác vụ. Ví dụ: mã bên dưới sẽ đợi năm phút trước khi bắt đầu tác vụ.

TimeSpan TimeToWait = TimeSpan.FromMinutes(5); 
Timer t = new Timer((s) => 
    { 
     // start the task here 
    }, null, TimeToWait, TimeSpan.FromMilliseconds(-1)); 

TimeSpan.FromMilliseconds(-1) làm hẹn giờ một lần chứ không phải định kỳ.

+0

Liệu công việc đó? Có vẻ như bộ đếm thời gian có thể lấy GCd sau khi nó vượt ra khỏi phạm vi, và trước khi sự kiện của tôi bị sa thải ... Trong mọi trường hợp, tôi đã hy vọng một thứ gì đó có nguồn gốc từ TPL (ví dụ, thực hiện một nhiệm vụ như là một cuộc tranh luận và cho phép hành động Maangement), mà dường như không tồn tại. – Slaggg

+0

Có, trong ví dụ đó, bộ hẹn giờ có thể được thu thập. Khai báo tham chiếu Timer ở ​​phạm vi sẽ ngăn chặn việc thu thập sớm. –

+0

OK - cảm ơn bạn đã trả lời. Tôi đã đề cập trong câu hỏi rằng một bộ đếm thời gian sẽ hoạt động; tôi đã hy vọng cho một cái gì đó mà đối phó với các đối tượng Task nguyên bản. Cảm ơn bạn mặc dù! – Slaggg

22

Tính năng này được giới thiệu trong Async CTP, hiện đã được cuộn vào .NET 4.5. Làm như sau không chặn luồng, nhưng trả về một Tác vụ sẽ thực hiện trong tương lai.

Task<MyType> new_task = Task.Delay(TimeSpan.FromMinutes(5)) 
          .ContinueWith<MyType>(/*...*/); 

(Nếu sử dụng async cũ phát hành, sử dụng lớp tĩnh TaskEx thay vì Task)

+1

Hoặc đơn giản là chờ đợi Task.Delay (TimeSpan.FromMinutes (5)); http://msdn.microsoft.com/en-us/library/hh194873(v=vs.110).aspx –

+0

+1, nhưng bất kỳ lựa chọn không ngủ nào cho .NET 4? (Tôi đang sử dụng cách tiếp cận được thiết kế quá mức bằng cách sử dụng chuỗi đơn có hàng đợi ưu tiên dựa trên heap mà chỉ bắt đầu nhiệm vụ mới khi thời gian của họ đến, được thiết kế quá mức khi quản lý hàng đợi ưu tiên không phải là miễn phí) –

+0

@MiloszKrajewski 'Task.Delay' không ngủ! Nói chung, ngủ một 'Task' (thread) đánh bại mục đích thiết kế và triết lý của' System.Threading.Tasks.Task' hoàn toàn, và không được khuyến khích. Ngủ sẽ không bao giờ là cơ sở của một '.NET' API dựng sẵn như' Task.Delay'; thay vào đó nó phụ thuộc vào bộ lập lịch trong hạt nhân hệ điều hành để tạo một tác vụ không thực thi cho đến khi hết hạn. Ngoài ra, Chris đã đề xuất 'await', trong trường hợp' Delay' có thể không kết thúc bằng cách sử dụng một chuỗi phụ nào cả, vì 'async' /' await' cho phép các luồng đơn đóng góp tiến trình về nhiều hoạt động "bị chặn". –

11

Bạn có thể viết hàm RunDelayed của riêng bạn. Điều này có một sự chậm trễ và một chức năng để chạy sau khi sự chậm trễ hoàn thành.

public static Task<T> RunDelayed<T>(int millisecondsDelay, Func<T> func) 
    { 
     if(func == null) 
     { 
      throw new ArgumentNullException("func"); 
     } 
     if (millisecondsDelay < 0) 
     { 
      throw new ArgumentOutOfRangeException("millisecondsDelay"); 
     } 

     var taskCompletionSource = new TaskCompletionSource<T>(); 

     var timer = new Timer(self => 
     { 
      ((Timer) self).Dispose(); 
      try 
      { 
       var result = func(); 
       taskCompletionSource.SetResult(result); 
      } 
      catch (Exception exception) 
      { 
       taskCompletionSource.SetException(exception); 
      } 
     }); 
     timer.Change(millisecondsDelay, millisecondsDelay); 

     return taskCompletionSource.Task; 
    } 

Sử dụng nó như thế này:

public void UseRunDelayed() 
    { 
     var task = RunDelayed(500,() => "Hello"); 
     task.ContinueWith(t => Console.WriteLine(t.Result)); 
    } 
+0

Tôi tin rằng bộ hẹn giờ của bạn có thể được thu thập rác trước khi thực hiện vì bạn không có tham chiếu bên ngoài nào. – newdayrising

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