Yalnızca DateTimeOffset
değerini kabul eden Timer aşırı yüklenmesini kullanın. Bir "mutlak aralık" oluşturmak için Defer
ve Repeat
'u kullanabilirsiniz. Bildirim bile zamanlayıcı sürüklenme açısından ve zamanlayıcı süresi öncesinde sistem saati değişiklikleri geçtikten, belirtilen kesin bir tarih ve saatte gerçekleşecek yönündeki elverdiğince
Observable.Defer(() =>
DateTime.Now.Hour < 9
? Observable.Timer(DateTime.Today.AddHours(9))
: DateTime.Now.Hour < 13
? Observable.Timer(DateTime.Today.AddHours(13))
: Observable.Timer(DateTime.Today.AddDays(1).AddHours(9)))
.Repeat()
.Subscribe(...);
Rx automatically ensures,.
Sorunu daha da genelleştiren bir uzantı yöntemi.
Kullanımı:
Observable2.Daily(TimeSpan.FromHours(9), TimeSpan.FromHours(13)).Subscribe(...);
Tanımı:
public static partial class Observable2
{
public static IObservable<long> Daily(params TimeSpan[] times)
{
Contract.Requires(times != null);
Contract.Requires(Contract.ForAll(times, time => time > TimeSpan.Zero));
Contract.Requires(Contract.ForAll(times, time => time.TotalDays < 1));
return Daily(Scheduler.Default, times);
}
public static IObservable<long> Daily(IScheduler scheduler, params TimeSpan[] times)
{
Contract.Requires(times != null);
Contract.Requires(Contract.ForAll(times, time => time > TimeSpan.Zero));
Contract.Requires(Contract.ForAll(times, time => time.TotalDays < 1));
if (times.Length == 0)
return Observable.Never<long>();
// Do not sort in place.
var sortedTimes = times.ToList();
sortedTimes.Sort();
return Observable.Defer(() =>
{
var now = DateTime.Now;
var next = sortedTimes.FirstOrDefault(time => now.TimeOfDay < time);
var date = next > TimeSpan.Zero
? now.Date.Add(next)
: now.Date.AddDays(1).Add(sortedTimes[0]);
Debug.WriteLine("Next @" + date + " from " + sortedTimes.Aggregate("", (s, t) => s + t + ", "));
return Observable.Timer(date, scheduler);
})
.Repeat()
.Scan(-1L, (n, _) => n + 1);
}
}
Güncelleme:
Eğer giriş tanımlayarak yaklaşımı daha "işlevsel" olmasını istiyorsanız Bir yineleyiciden sonsuz bir sıra olarak Jeroen Mostert'ın cevabı uyarınca, aşağıdaki gibi Generate
kullanabilirsiniz.
Observable.Generate(
GetScheduleTimes().GetEnumerator(),
e => e.MoveNext(),
e => e,
e => e.Current,
e => e.Current);
Jeroen Mostert cevabı ( silinmiş) GetScheduleTimes
bir örnek uygulamasını temin ama temelde değerleri artan her döngü ile bir süre döngü içinde DateTimeOffset
değerlerinden sonsuz serisini vermiştir sadece bir yineleyici blok gün tarafından 1.
Bir sonraki tetikleyiciye kadar olan zamanı hesaplayabilir ve bu zaman aşımına sahip bir zamanlayıcı kullanabilirsiniz ([Threading.Timer] içinde http://www.msdn.microsoft.com/en- us/library/3yb9at7c (v = vs.110) .aspx)) – Jcl
Kodunuzu Windows Görev Zamanlayıcısını kullanabileceğiniz şekilde yazın. d için. – JRLambert