3

IIS でホストされている WCF Web サービスがあります。

それにはメソッドがあります(「ConfirmOrder」と呼びましょう)。このメソッドが呼び出されたら、次のことを行います。 1. データベースに対していくつかの簡単な処理を実行し、OrderId を生成します。 2. 遅い処理を実行する新しいスレッドを開始します (たとえば、電子メールを生成して送信します)。 3. から OrderId を返します。 1. クライアントと同期。4. 最終的に、2. で作成された新しいスレッドは、残りのすべての処理を完了してメールを送信します。

質問:

(1)次のようなコードがありました:

// do printing and other tasks 
OrderConfirmedThreadHelper helper = new OrderConfirmedThreadHelper(userSession, result);
// some things first (like generating barcodes) in this thread 
Logger.Write(basket.SessionId, String.Format("Before ConfirmOrderSync"), LogCategoryEnum.Sales, System.Diagnostics.TraceEventType.Verbose);
helper.ConfirmOrderSync();
Logger.Write(basket.SessionId, String.Format("After ConfirmOrderSync"), LogCategoryEnum.Sales, System.Diagnostics.TraceEventType.Verbose);
// slower things (like rendering, sending email) in a separate thread
Thread helperThread = new Thread(new ThreadStart(helper.ConfirmOrderAsync));
helperThread.Start();
return result;

しかし、それは問題を引き起こしているようでした。少なくとも、サービスはロックし続けました。これは悪いことですか?

(2) に変えてみた

// slower things (like rendering, sending email) in a separate thread            
ThreadPool.QueueUserWorkItem(new WaitCallback(helper.ConfirmOrderAsync));

しかし、ThreadPool スレッドはバックグラウンド スレッドであるため、メイン スレッドが終了するとすぐに強制終了されているようです。

これを行うためのより良い方法はありますか?通信するためのまったく新しい Windows サービスを作成する以外に?

4

1 に答える 1

0

リクエスト スレッド (ブラウザからのスレッド) の後に 2 番目のスレッドが終了すると、ランタイムによって回収されて終了するため、問題が発生します。待つ余裕がある場合 (電子メールを送信するだけの場合は数秒かかります)、ManualResetEvent を使用して一方のスレッドを同期し、もう一方のスレッドが終了して適切にクリーンアップするのを待つことができます。

待てない場合、この場合のメール プロセスの最適な選択は次のいずれかです。

  1. Windows サービス。
  2. メールを送信するために必要なデータを渡す jquery ajax 呼び出しを使用して、クライアント コードから呼び出すことができる .ashx。
  3. 送信待ちのメールをDBから読み込んで送信するバッチジョブ(スケジュールタスク、SQLサーバージョブなど)です。X分ごとに実行されるので、心配する必要はありません

それが役立つことを願っています!

于 2012-09-17T18:57:14.533 に答える