1

Windows サービスでタイマーを使用しています。これはシンプルで、イベントが経過するたびにファイルにデータを書き込むことができます。このアプリケーションでは、3 種類のケースを実装しようとしています。

  1. イベントは毎日同じ時間 (指定された StartTime) に発生します。

  2. 特定の WeekDays で発生するイベントは、特定の StartTime から始まる月曜日、火曜日、および土曜日にのみ実行したいと言っています。

  3. いくつかの特定の月に発生するイベントとその月の特定の平日は、7 月と 9 月にのみ実行したいが、特定の StartTime から始まる月曜、火曜、土曜の制限された日に実行したいと言っています。

今まで私が実装したのはケース 1 であり、ケース 2 とケース 3 で同じことを行う方法についてはわかりません (私が考えているロジックは奇妙です)。ケース 2 の解決に助けがあれば、ケース 3 の実装にも役立ちます。その他の提案は大歓迎です。

ここに私のコードがあります:

   private static Timer aTimer;
        public static void Main()
        {
            aTimer = new System.Timers.Timer(2000);
             aTimer.Elapsed += OnTimedEvent;
            aTimer.Enabled = true;

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

        private static void OnTimedEvent(Object source, ElapsedEventArgs e)
        {

            String path = @"E:\sample1.txt";
            StreamWriter osw = new StreamWriter(path, true);
          Console.WriteLine("Enter the  case (1 or 2 or 3)");
                var ch = int.Parse(Console.ReadLine());
                //throw new NotImplementedException();
                   switch (ch)
                {
                    default:  break;
                    case 1:aTimer = new System.Timers.Timer();
                        aTimer.Elapsed += OnTimedEventCase1;
                        aTimer.Enabled = false; 
                        break;
                    case 2: aTimer = new System.Timers.Timer();
                           aTimer.Elapsed += OnTimedEventCase2;
                        aTimer.Enabled = false; 
                        break;
                    case 3: aTimer = new System.Timers.Timer();
                          aTimer.Elapsed += OnTimedEventCase3;
                        aTimer.Enabled = false; 
                        break;
                }

            osw.Close();
            osw = null;
           }
// Elapsed Event for Case 1
      private void OnTimedEventCase1(object source, ElapsedEventArgs e)
            {
                //throw new NotImplementedException();
                Console.WriteLine("Daily Job");
                Console.WriteLine("DateTime: " + DateTime.Now);
                Timer theTimer = (System.Timers.Timer)source;
                theTimer.Interval = 1000 * 24 * 60 * 60; // will do it daily i.e, 24 hours
                theTimer.Enabled = true;
        }
// Elapsed Event for Case 2
     private void OnTimedEventCase2(object source, ElapsedEventArgs e)
        {
          //  throw new NotImplementedException();
            string[] days = new string[]{"Monday", "Tuesday" ,"Saturday"};
            Console.WriteLine("WeekDays Job");
            Console.WriteLine("DateTime: " + DateTime.Now);
            Timer theTimer = (System.Timers.Timer)source;
            //theTimer.Interval = I don't know how to fire event here according weekdays  
            //theTimer.Enabled = true;

        }
// Elapsed Event for Case 3
      private void OnTimedEventCase3(object source, ElapsedEventArgs e)
        {
          //  throw new NotImplementedException();
            string[] days = new string[]{"Monday", "Tuesday" ,"Saturday"};
            string[] months= new string[]{"July", "September"};
            Console.WriteLine("Monthly job");
            Console.WriteLine("DateTime: " + DateTime.Now);
            Timer theTimer = (System.Timers.Timer)source;
            //theTimer.Interval = I don't know how to fire event here according months and then weekdays
            //theTimer.Enabled = true;

        }

何時間も経過したイベントを簡単に実装できますが、一定の時間である1日でもtimeInterval属性を渡す必要がありますが、選択した平日と選択した月の経過イベントを発生させる方法がわかりません。

4

2 に答える 2

1

I would be inclined to use Microsoft's Reactive Framework (NuGet "Rx-Main") for this. It would be much simpler.

Here's the hardest part:

IObservable<DateTimeOffset> daily =
    Observable
        .Create<long>(o =>
        {
            var startTime = DateTimeOffset.Now.Date.Add(new TimeSpan(15, 30, 0));
            if (startTime < DateTimeOffset.Now)
            {
                startTime = startTime.AddDays(1.0);
            }
            return Observable.Timer(startTime, TimeSpan.FromDays(1.0)).Subscribe(o);
        })
        .Select(n => DateTimeOffset.Now);

This code sets up an observable that will fire first at the time specified in the new TimeSpan(15, 30, 0) and then every day as specified in the TimeSpan.FromDays(1.0). The .Select(n => DateTimeOffset.Now) means that the sequence will return the actual DateTimeOffset that it fired.

Now you just have to apply filters to get the other two observables you need:

IObservable<DateTimeOffset> weekday =
    from n in daily
    where new []
    {
        DayOfWeek.Monday,
        DayOfWeek.Tuesday,
        DayOfWeek.Saturday,
    }.Contains(n.DayOfWeek)
    select n;

IObservable<DateTimeOffset> monthWeekday =
    from n in weekday
    where new [] { 7, 9, }.Contains(n.Month)
    select n;

They are basically LINQ queries that filter out the events from daily that you don't want to fire.

Then you just need to add the code that actually consumes the events:

IDisposable dailySubscription =
    daily
        .Subscribe(n =>
        {
            /* daily work goes here */
        });

IDisposable weekdaySubscription =
    weekday
        .Subscribe(n =>
        {
            /* weekday work goes here */
        });

IDisposable monthWeekdaySubscription =
    monthWeekday
        .Subscribe(n =>
        {
            /* month/weekday work goes here */
        });

All you need to do to shut down each subscription is to call .Dispose() on them.

于 2015-06-08T10:32:57.077 に答える