4

このシナリオをしっかりと理解したいので、この投稿を正当な StackOverflow の質問に形作りたいと思っていますが、それがあまりにもローカライズされているか、「意見」と見なされているかどうかは間違いなくわかります。

これが私のシナリオです: Web アプリをロードするとき、データベースから大量のデータをロードしてキャッシュします。問題は、このプロセスに約 10 ~ 15 秒かかり、Web サーバーの最初の起動時に遅延が生じることです。これは開発中はちょっと厄介で、実稼働環境で Web サーバーをバウンスするときにいくつかの問題が発生します (これは新しいサイトなので、小さなバグを見つけたら修正したり、IIS の設定をいじったりすることがよくあります)。

私は疑問に思いました - アプリケーションの開始時にこの作業を新しいスレッドにオフロードし、他のユーザーがサイトを使用しているときにバックグラウンドでこれを実行できますか? 明らかに、サイトがロードされたときに特定の機能が約 10 ~ 15 秒間動作しませんでしたが、データが利用可能になるまで、その状態を処理またはブロックできます。最初はノーと思っていました。Web サーバーは、要求が終了した場合にこれらのスレッドを終了するか、これらのスレッドが終了するまでブロックしようとしていました。この理論をテストするために、小さなテスト アプリを作成することにしました。

public class Global : System.Web.HttpApplication
{
   void Application_Start(object sender, EventArgs e)
   {
      Thread thread = new Thread(LoadData);
      thread.Start();
   }

   private void LoadData()
   {
      for (int i = 0; i < 100; i++)
      {
         Trace.WriteLine("Counter: " + i.ToString());
         Thread.Sleep(1000);
      }
   }
}

アプリが起動したら、新しいスレッドを起動し、それを 100 までカウントします。驚いたことに、すぐにホーム ページに移動し、Visual Studio のデバッグ出力ウィンドウで、数値が増加するのを確認できました。私は実際にこれが機能することに驚きました。

私の質問:

まず、これを行う際に落とし穴はありますか? それはトラブルを求めていて、何かが爆発しようとしていますか? おそらく異なるスレッド モデルを使用しているため、この動作は Web サーバーまたは IIS のバージョン間で変化しますか? このデザインに関する全体的なフィードバックを探しています。

4

2 に答える 2

2

tl;dr:あなたがしていることはおそらく問題なく、この状況に対処する一般的な方法です。

スレッドには確かに落とし穴があります。この場合にそれらを使用すべきではないと言っているわけではありませんが、それらを理解していることを確認するのが賢明です. 古いミームを悪用するには、「プログラマーは並行性の問題をよく目にし、別のスレッドを使用して解決します。現在、2 つの問題があります。」

スレッドがバックグラウンド スレッドであることを意図している場合 (つまり、スレッドがまだ実行されている場合にサイトのシャットダウンを妨げてはならないことを意味します)、IsBackground プロパティが設定されていることを確認してください。さらに良いことに、 BackgroundWorkerを使用してください。

初期化スレッドが完了する前に、あなたのサイトはどの程度使いやすいでしょうか? 初期化中にインターフェイスを表示する本当の理由はありますか?

私は並行処理のためにスレッドを直接使用することに一周しました - スレッドが怖いから、理解していると思って受け入れる、理解していると思って怖がるまで。現在、解決したい並行性/非同期の問題がある場合、通常、複数の相互通信する並行 (ただしシングルスレッド) プロセスで構成されるアーキテクチャを作成しようとします。そうすることで多くのことが簡単になり、私はそれで多くの成功を収めてきました。

現在のケースでは、バックグラウンド スレッドを使用してデータベースの負荷を処理することは、スレッドが準備する前にリソースにアクセスしないことを保証できれば、おそらく十分に安全です。ただし、(.Net 4.0 をターゲットにできる場合)、必要なことを行うためのより良い方法は、Task Asyncライブラリを活用することです。つまり、ルーチンを非同期に記述し、T ではなく T の Task を返します。自体。これを正しく行うと、シングル スレッド環境であっても、バックグラウンドでリソースを読み込んでいるときでも、サイトをユーザーに応答させることができます。

于 2012-10-16T21:32:53.323 に答える
1

落とし穴は、そこにないキャッシュから何かを使用するときです。

BackGroundWorker のように Drew に同意します。

サイトには、キャッシュに依存する機能が無効になっている 2 つのモードが必要です。
BackGroundWorker が完成したら、すべての機能をオンにします。
ユーザーは、ボタンをクリックして準備ができていないと通知されることを好みません。後でもう一度やり直してください。

于 2012-10-16T21:42:28.277 に答える