2008-11-11 26 views
13

Có phương pháp thông minh nào để thực hiện hàm executeEveryDayMethod() của tôi mỗi ngày một lần mà không cần phải liên quan đến Windows TaskScheduler không?Chạy một lần một ngày

Trân

/Anders

+1

là ứng dụng của bạn không ngừng chạy? Nó là một dịch vụ? Bạn có thể cung cấp thêm một chút thông tin về các điểm này –

Trả lời

7

Hãy xem quartz.net. Nó là một thư viện lập lịch cho .net.

Cụ thể hơn, hãy xem here.

+2

"Sau hơn hai năm phát triển, sửa lỗi và các tính năng mới Quartz.NET cuối cùng đã trưởng thành lên phiên bản 1.0." Tôi biết lịch trình là khó hơn rất nhiều so với cái nhìn đầu tiên. Hai năm và cho một bản sao! –

+1

Mọi người quên đề cập đến việc hoàn toàn miễn phí mà không có giới hạn GPL (giấy phép Apache: o) – wcm

3

Nếu thời gian khi nó được chạy là không phù hợp và có thể được thiết lập lại mỗi khi chương trình bắt đầu bạn chỉ có thể thiết lập một bộ đếm thời gian, đó là điều dễ nhất để làm. Nếu điều đó không thể chấp nhận, nó bắt đầu trở nên phức tạp hơn, như giải pháp được trình bày here và vẫn không giải quyết được vấn đề dai dẳng, bạn cần giải quyết một cách riêng biệt nếu bạn thực sự muốn thực hiện Tác vụ theo lịch nào. Tôi thực sự sẽ xem xét một lần nữa nếu nó có giá trị đi qua tất cả các rắc rối để nhân rộng một chức năng hoàn toàn tốt hiện có.

Đây là số related question (Ví dụ được lấy từ đó).

using System; 
using System.Timers; 

public class Timer1 
{ 
    private static Timer aTimer = new System.Timers.Timer(24*60*60*1000); 

    public static void Main() 
    { 
     aTimer.Elapsed += new ElapsedEventHandler(ExecuteEveryDayMethod); 
     aTimer.Enabled = true; 

     Console.WriteLine("Press the Enter key to exit the program."); 
     Console.ReadLine(); 
    } 

    // Specify what you want to happen when the Elapsed event is 
    // raised. 
    private static void ExecuteEveryDayMethod(object source, ElapsedEventArgs e) 
    { 
     Console.WriteLine("The Elapsed event was raised at {0}", e.SignalTime); 
    } 
} 
+0

Xem nhận xét @ZombieSheep – StingyJack

+0

Xem đoạn đầu tiên :-) –

0

Bạn có thể truy vấn thời gian và chạy nếu bạn trong một số khung thời gian, như vậy ngay cả khi máy tắt đi bạn sẽ gọi phương thức hoặc sử dụng một bộ đếm thời gian như gợi ý Vinko của.

Nhưng giải pháp tốt hơn (giống như phiên bản CRON cũ hơn, do đó, một mẫu đã được chứng minh) là có một số dữ liệu liên tục, với giải pháp rẻ nhất tôi có thể nghĩ là tệp trống, kiểm tra thuộc tính đã sửa đổi cuối cùng của nó và nếu nó chưa được sửa đổi trong vòng 24 giờ qua, bạn chạm vào nó và chạy phương thức của bạn. Bằng cách này, bạn đảm bảo phương pháp được chạy điều đầu tiên trong trường hợp ứng dụng được ra cho cuối tuần ví dụ.

Tôi đã làm điều này trong C# trước đây, nhưng nó đã được một năm trước tại một công việc khác, vì vậy tôi không có mã nhưng nó là khoảng 20 dòng (với ý kiến ​​và tất cả) hoặc như vậy.

16

tôi đạt được điều này bằng cách làm như sau ...

  1. Thiết lập một bộ đếm thời gian mà bắn mỗi 20 phút (mặc dù thời gian thực tế là tùy thuộc vào bạn - Tôi cần phải chạy trên nhiều lần trong suốt cả ngày) .
  2. trên mỗi sự kiện Tick, hãy kiểm tra thời gian của hệ thống. So sánh thời gian với thời gian chạy theo lịch cho phương pháp của bạn.
  3. Nếu thời gian hiện tại nhỏ hơn thời gian đã lên lịch, hãy kiểm tra trong một số lưu trữ liên tục để nhận giá trị datetime của lần cuối cùng phương thức chạy.
  4. Nếu phương pháp cuối cùng chạy hơn 24 giờ trước, hãy chạy phương thức và lưu lại ngày giờ chạy trở lại kho dữ liệu của bạn
  5. Nếu phương pháp cuối cùng chạy trong vòng 24 giờ qua, hãy bỏ qua nó.

HTH

* chỉnh sửa - mẫu mã trong C# :: Lưu ý: chưa được kiểm tra ...

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Timers; 

namespace ConsoleApplication2 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Timer t1 = new Timer(); 
      t1.Interval = (1000 * 60 * 20); // 20 minutes... 
      t1.Elapsed += new ElapsedEventHandler(t1_Elapsed); 
      t1.AutoReset = true; 
      t1.Start(); 

      Console.ReadLine(); 
     } 

     static void t1_Elapsed(object sender, ElapsedEventArgs e) 
     { 
      DateTime scheduledRun = DateTime.Today.AddHours(3); // runs today at 3am. 
      System.IO.FileInfo lastTime = new System.IO.FileInfo(@"C:\lastRunTime.txt"); 
      DateTime lastRan = lastTime.LastWriteTime; 
      if (DateTime.Now > scheduledRun) 
      { 
       TimeSpan sinceLastRun = DateTime.Now - lastRan; 
       if (sinceLastRun.Hours > 23) 
       { 
        doStuff(); 
        // Don't forget to update the file modification date here!!! 
       } 
      } 
     } 

     static void doStuff() 
     { 
      Console.WriteLine("Running the method!"); 
     } 
    } 
} 
+0

Vấn đề về Clbluttic với Bộ hẹn giờ và đã trôi qua ... Kiểm tra xem khi nào lần đầu tiên chạy đã bị loại trừ hay không có lời gọi của phương thức doStuff() trước khi bộ đếm thời gian bắt đầu tích tắc. Nếu bạn có thời gian chờ 24 giờ, bạn sẽ thấy các chương trình là 'đã chết' trong một ngày. – StingyJack

+0

Điểm tốt! Như tôi đã nói, nó đã không được thử nghiệm và tôi đã hoàn toàn quên để thực hiện hành vi 'chạy đầu tiên'. Lỗi của tôi! – ZombieSheep

0

Có thể có vấn đề nếu máy tính khởi động lại, do đó bạn có thể chạy các ứng dụng như một cửa sổ dịch vụ.

0

Để chạy công việc một lần mỗi ngày từ 7 đến 8 giờ tối, tôi thiết lập bộ hẹn giờ với khoảng thời gian = 3600000 ms và sau đó chỉ cần thực thi mã sau đây để đánh dấu hẹn giờ.

private void timer1_Tick(object sender, EventArgs e) 
{ 
    //ensure that it is running between 7-8pm daily. 
    if (DateTime.Now.Hour == 19) 
    { 
     RunJob(); 
    } 
} 

Cửa sổ giờ là tốt cho tôi. Thêm chi tiết về thời gian sẽ yêu cầu một khoảng thời gian nhỏ hơn trên bộ đếm thời gian (60000 cho một phút) và bao gồm cả phút trên nếu.

ví dụ

{ 
    //ensure that it is running at 7:30pm daily. 
    if (DateTime.Now.Hour == 19 && DateTime.Now.Minute == 30) 
    { 
     RunJob(); 
    } 
} 
Các vấn đề liên quan