背景に大量の電子メールを送信する - スレッドを作成するか、スレッドプールを使用しますか?

StackOverflow https://stackoverflow.com/questions/4138405

質問

アクションが送信される多数のメールをトリガーするアプリケーションがあります。電子メールの数は可変であり、10〜1,000のどこにでもあることがあります アクションごと.

アプリケーションを望んでいません 下がる 電子メールが送信されている間(したがってユーザーを悩ませている)、バックグラウンドでそれらを送信したい。

私は過去にスレッドを使用していなかったので、あなたの助けが必要です。手動でスレッドを作成しますか、それともスレッドプールを使用するのに適したケースですか?このタスクは優先度が低く、メールが1時間遅れても気にしないため、可能な限り最小限のリソースを使用したいと思います。

あなたの助けに感謝
マルコ

役に立ちましたか?

解決

ここに別の提案があります... DBを使用している場合、送信して使用する必要があるメッセージに関連するタスクを作成します(つまり、実行するタスクを表すテーブルを作成します) Quartz.net または同様の(Windowsサービスも作成できます)。これは、不完全なタスクを探して実行します(それらが正常に実行された場合に行われたようにマークします)。

他のヒント

正直なところ、ASP.NETでのスレッドは良い考えではありません。 ASP.NETは、リクエストが終了し、ユーザーに投稿したときにリソースを多く廃棄します。ユーザーに待機したくないので、このシナリオに遭遇します。このシナリオは、使用しても安全だと思われるASP.NETオブジェクトが本当に処分されます。

最良のオプションは、外部サービス(IISで実行されているWCFサービス、または.NETページが非同期に呼び出すことができるWCFインターフェイスがあるWindowsサービス)を作成し、完了するまでその要求を実行することです。スレッドなどを心配することはありません。それはそれ自体のプロセスで実行され、完了すると完了します。ユーザーに完了したことを伝えることは気にしないので、それが戻ってコミュニケーションをとることを心配する必要はありません。これにより、他のページに同じサービスインターフェイスを使用する必要がある場合は、呼び出されます。

WCFを始めたページ:

http://bloggingabout.net/blogs/dennis/archive/2007/04/20/wcf-simple-example.aspx

http://msdn.microsoft.com/en-us/library/bb332338.aspx

http://www.c-sharpcorner.com/articles/articlelisting.aspx?sectionid=1&subsectionId=192

WCF/WPFの使用を開始する方法は?

したがって、私の提案は、ThreadPoolを使用することです。代わりにそれぞれを個別に実行するためにすべてをキューに並べることができ、リソースを使用することが少なくなりますが、もちろん、すべてを処理するのに時間がかかりますが、あなたが言ったように、時間は問題ではありません。

単に使用できます バックグラウンドワーカー クラス。

リンクされたMSDNページには、進捗状況の報告と操作をキャンセルする可能性がある素晴らしい例があります。

編集:
進捗報告とキャンセルはWebアプリケーションでは適していない場合がありますが、バックグラウンドワーカーは、すべての汚れたものを、スレッドを作成することで処理します。

編集2:
多くのメールを並行して送信したい場合は、 タスクパラレルライブラリ.

タスクを使用して、ワーカースレッドから出て、電子メールを処理できます。

これがCPUをあまりにも多く叩いている場合は、並行性を低下させる新しいスケジューラを作成できます。 http://msdn.microsoft.com/en-us/library/ee789351.aspx

static void StartMailTasks(string[] addresses)
{
    List<Task> tasks = new List<Task>();
    foreach (var address in addresses)
    {
        tasks.Add(Task.Factory.StartNew(Email, address));
    }

    Task.Factory.ContinueWhenAll(tasks.ToArray(), AllDone, TaskContinuationOptions.OnlyOnRanToCompletion);
    Task.Factory.ContinueWhenAny(tasks.ToArray(), ReportError, TaskContinuationOptions.OnlyOnFaulted);
}

static void AllDone(Task[] tasks)
{
    // All is well
}

static void ReportError(Task errorTask)
{
    // Log or report the error
}

static void Email(object state )
{
    // send the e-mail  
    // Can throw error, if needed
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top