申し訳ありませんが、タイトルが少しくだらないので、正しく表現できませんでした。
編集:これはコンソールc#アプリであることに注意してください
私はそのように機能するシステムのプロトタイプを作成しました(これは大まかな疑似コードです):
var collection = grabfromdb();
foreach (item in collection) {
SendAnEmail();
}
メールを送る:
SmtpClient mailClient = new SmtpClient;
mailClient.SendCompleted += new SendCompletedEventHandler(SendComplete);
mailClient.SendAsync('the mail message');
SendComplete:
if (anyErrors) {
errorHandling()
}
else {
HitDBAndMarkAsSendOK();
}
明らかに、この設定は理想的ではありません。最初のコレクションにたとえば10,000レコードがある場合、行をステップスルーできる限り迅速に、smtpclientの10,000インスタンスをかなり短い順序で新規作成します。
私の理想的なエンドゲームは、10通の同時メールを一度に送信することです。
ハッキーな解決策が思い浮かびます。SendAnEmail()が呼び出されると増加し、SendCompleteが送信されると減少するカウンターを追加します。最初のループでSendAnEmail()が呼び出される前に、カウンターをチェックします。カウンターが高すぎる場合は、少しの間スリープしてから、もう一度チェックします。
それがそんなに素晴らしいアイデアかどうかはわかりませんが、SOハイブマインドがこれを適切に行う方法があると考えています。
私はスレッディングについてほとんど知識がなく、ここでそれが適切な使用法であるかどうかはわかりません。たとえば、バックグラウンドスレッドでメールを送信する場合は、最初に子スレッドの数をチェックして、使用されているスレッドが多すぎないことを確認します。または、何らかのタイプの「スレッドスロットリング」が組み込まれている場合。
アップデート
スティーブンA.ロウのアドバイスに従って、私は今持っています:
- 私の電子メールと一意のキーを保持する辞書(これは電子メールのキューです
- 辞書に入力するFillQueメソッド
- バックグラウンドスレッドであるProcessQueメソッド。キューをチェックし、キュー内のすべての電子メールをSendAsycsします。
- キューから電子メールを削除するSendCompletedデリゲート。そして、FillQueを再度呼び出します。
この設定にはいくつか問題があります。バックグラウンドスレッドでボートを逃したと思いますが、辞書の各アイテムに対してこれらの1つをスポーンする必要がありますか?電子メールのキューがスレッドの終わりを空にした場合、より良い単語がないためにスレッドを「ぶらぶら」させるにはどうすればよいですか。
最終更新
'while(true){}'をバックグラウンドスレッドに入れました。キューが空の場合、数秒待ってから再試行します。キューが繰り返し空になる場合は、しばらくの間「中断」してプログラムを終了します...正常に動作します。私は「while(true)」ビジネスについて少し心配しています。