0

アクションによって多数の電子メールが送信されるアプリケーションがあります。メールの数は可変であり、アクションごとに10〜1,000の範囲で指定できます。

電子メールの送信中にアプリケーションがハングしたくない(したがってユーザーを煩わせる)ので、バックグラウンドで送信したいと思います。

私は過去にスレッドを使用したことがないので、あなたの助けが必要です。スレッドを手動で作成しますか、それともThreadPoolを使用するのに適していますか?メールが1時間遅れてもかまわないので、このタスクの優先度を低くし、リソースの使用量をできるだけ少なくしたいと思います。

マルコの助けに感謝します

4

5 に答える 5

3

正直なところ、ASP.NETでのスレッド化はお勧めできません。Asp.netは、要求が終了してユーザーにポストバックするときに、多くのリソースの破棄を行います。ユーザーを待たせたくないので、このシナリオに遭遇します。このシナリオでは、安全に使用できると思われるASP.NETオブジェクトが実際に破棄されます。

最善のオプションは、.netページが非同期で呼び出すことができる外部サービス(IISで実行されているwcfサービス、または公開されている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の使用を開始するにはどうすればよいですか?

于 2010-11-09T20:50:58.567 に答える
1

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

于 2010-11-10T00:19:16.657 に答える
0

単純にBackgroundWorkerクラスを使用できます。

リンクされたMSDNページには、進行状況のレポートと操作をキャンセルする可能性のある良い例があります。

編集:
進行状況のレポートとキャンセルはWebアプリケーションには適していない可能性がありますが、BackgroundWorkerはスレッドを作成してすべての汚いものを処理します。

Edit2:
多数のメールを並行して送信したい場合は、タスク並列ライブラリを参照してください。

于 2010-11-09T20:51:06.947 に答える
0

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

于 2010-11-09T20:47:57.850 に答える
0

タスクを使用して、電子メールを処理するためのワーカースレッドを生成できます。

これが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
}
于 2010-11-09T21:15:11.287 に答える