水差しの有効期限が切れたときにすぐに通知が必要な場合は、次の操作を実行できます。
Scan the list of jugs and find the one with the earliest expiration date
Set a timer to expire at that date/time.
When the timer expires, remove that jug from the list.
Scan the list of jugs to find any other jugs that expire at this time.
Send notifications for all the expired jugs.
Go to step 1.
このアルゴリズムにはいくつかの問題があります。
- 水差しを追加する場合は、その有効期限が現在の最も早い有効期限よりも前であるかどうかを確認する必要があります。その場合、現在の水差しの有効期限のタイマーをリセットする必要があります。
- 同様に、リストから水差しを削除した場合、それが有効期限を待っている水差しかどうかを確認する必要があります。もしそうなら、あなたは新しい最も古いジャグを見つけて、タイマーをリセットしなければなりません.
- 水差しの非常に大きなリストをスキャンすると、費用がかかる可能性がありますが、水差しの有効期限が切れたときにのみ実行する必要があります.
リストを並べ替えることで、リストをスキャンする必要がなくなります。次に、最も早い有効期限が常にリストの一番上にあることがわかります。新しいジャグを追加するときは、有効期限までに挿入するだけです。二分探索を使用して、挿入する場所を決定できます。
または、優先キュー (バイナリ ヒープまたはスキップ リスト) を使用して、有効期限ごとに水差しを保存することもできます。どのデータ構造を使用するかは、アイテムの数と更新頻度によって異なります。ジャグが多く、頻繁にアクセスするほど、効率的なデータ構造に注意を払う必要があります。
このアプローチの優れた点は、水差しを期限切れにする必要がある場合にのみタイマーが作動することです。あなたは決して投票しません。
.NET で次のようなワンショット タイマーを作成するのは簡単です。
TimeSpan expirationDelay = jug.ExpirationDateTime - DateTime.Now;
System.Threading.Timer jugTimer = new System.Threading.Timer(
JugExpirationCallback, null, expirationDelay, TimeSpan.FromMilliseconds(-1));
コンストラクターの最後のパラメーターは、定期的なタイマーではなく、一度起動して終了するように指示します。その後、タイマーのChange
メソッドを呼び出して、次の水差しのタイマーを更新できます。
の計算ではexpirationDelay
夏時間が考慮されないことに注意してください。DateTime
それを行う場合は、計算を行う前に値を UTC に変換する必要があります。または、WaitableTimerを使用してそれを行うことができます。この記事の最後に、WaitableTimer ソースへのリンクがあります。
コメント後の追加情報
あなたのコメントの後、ログインしているユーザーに期限切れのジャグを通知したいのではないかと思います。おそらく、ログインしているユーザーごとに 1 つの水差し (有効期限が最も早いもの) を含むコレクション (リストまたは優先キュー) を使用します。ユーザーのアイテムの有効期限が切れると、データベース クエリを実行して、そのユーザーの次に有効期限が切れるアイテムを取得し、それをリストに追加できます。もちろん、これは、予想されるユーザーの数、各ユーザーの水差しの数、期限切れの頻度によって異なります。
それらをすべてメモリに保持しようとすることもできますが、更新を管理する必要があります。つまり、データベースが更新された場合、メモリ内表現も更新する必要があります。ユーザーごとに 1 つだけ保持する場合、その問題は大幅に簡素化されます。また、必要なメモリも大幅に削減されます。
リストへの入力方法に関係なく、基本的な考え方は変わりません。最も早いアイテムが期限切れになるときに起動するように構成されたタイマーを 1 つ作成します。各アイテムの有効期限が切れたら、次のアイテムのタイマーをリセットします。
リストにアイテムを追加する方法は、「単なる詳細」です。あなたのアプリケーションについて十分な知識がないため、これ以上具体的な推奨事項を作成することはできません。