2009-03-31 6 views
2

私は現在、現在のHttpContextを使用してLINQデータコンテキストを格納しているWebアプリケーションを持っています。コンテキストはRick Strahl's blogごと、ユーザーごとに、現在の要求のために保持されます:サーバーサイドのHttpContextに相当する?

string ocKey = "ocm_" + HttpContext.Current.GetHashCode().ToString("x") 
Thread.CurrentContext.ContextID.ToString(); 

if (!HttpContext.Current.Items.Contains(ocKey)) 
{ 
    // Get new Data Context and store it in the HTTP Context 
} 

しかし、私はのHttpContextを持っていないことを、Global.asaxファイルから実行するいくつかのスクリプトを持っています。 HttpContext.CurrentはNULLであり、サーバーは "要求"を出しているため、です。

データコンテキストの保存に使用できるオブジェクトはありますか?だから私はそれを再作成したり、オブジェクトを取り付けたり外したりすることについて心配する必要はありませんか?私は、自分のプロセスの生涯にわたってコンテキストを維持したいだけです。

更新:私は現在、私のDALヘルパークラスに静的変数を使用しようとしています

。クラス内のメソッドの1つへの最初の呼び出しで、DataContextがインスタンス化され、静的変数に格納されます。私のプロセスの終わりに、DataContextでDisposeを呼び出す別のメソッドを呼び出し、静的変数をNULLに設定します。

+0

スクリプトはどのイベントで実行されますか?私はSession_StartとEndを想定していますか? – JoshBerke

+0

定期的に実行するために作成されたタイマーがあります。これらはApplication_Startイベント中に作成されます。彼らは毎回頻繁に実行され、データベースをチェックしていくつかの電子メールを発します。 –

+0

明確にしてください - 現在のコンテキストを返すメソッドがあります(存在しない場合は新しいものを作成しています)。また、この同じメソッドは、HttpContextを使用可能にした場合と使用しない場合(タイマーコールバックで)の両方で動作します。右? – XOR

答えて

4

これらのスクリプト専用の静的変数は使用できませんか?それはAppDomainと同じ生涯を持ちます。おそらく、並行性の問題については注意深く考えなければなりませんが、値を保持する最も簡単な方法のように思えます。

(これまでチェックしたことがありますが、HttpApplicationの1つのインスタンスを使用して複数のリクエストを処理することはできますが、同時に1つのリクエストしか処理できません - 同時にリクエスト処理のために複数のインスタンスが作成されます。これを検証しましたが、インスタンス変数に保持するのが安全でないように思えます。)

EDIT:これはスレッドごとにすることをお勧めします。あなたがこれらのイベントのlotを持っていない限り、私は少し奇妙に聞こえるでしょう。あなたはそれらが異なるスレッドで実行されるのを見て、共有ビジネス全体を無意味なものにしてしまうでしょう。このようなことが本当に必要な場合は、HttpApplication由来のクラスのインスタンス変数を使用することをお勧めします。上記の文で説明した理由と同じです。

+0

ジョン、これが正しいです。各アプリケーションは、一度に1つの要求のみを処理します。 – XOR

+0

"展開された各Webアプリケーション"または "HttpApplicationの各インスタンス"を意味しますか? 1つのWebアプリケーションで複数のインスタンスが作成されていますか?デプロイされたアプリケーションへのすべてのリクエストをシリアル化することは、私にとってパフォーマンスの死のように聞こえます。確かにそれは物事の方法ではありません。 –

+0

私は、このWebアプリケーションの1つのインスタンスを1つのボックスでしか実行していません。私は、これらのプロセスをバックグラウンドで実行し、いくつかの作業をしたいだけです。実行時には、操作中にデータコンテキストを保持しておきたいので、再作成やエンティティの追加について心配する必要はありません。 –

1

なぜ現在のHttpContextを使用しないのですか?あなたのglobal.asaxファイル内のスクリプトはすべて、サーバーに入ってくるリクエストの結果なので、取得できるリクエストに関連したコンテキストが必要です。

私は、ハッシュコードまたはスレッドに基づいてキーを生成する必要性を理解していません。入ってくるリクエストごとに別々のHttpContextのインスタンスが存在し、そのインスタンスはリクエストを処理しているスレッドに固有のものになります。そのため、HttpContextとスレッドのインスタンスに基づいている場合、キーはほとんど無価値です。

また、完了したらどのようにDataContextを破棄しますか?それは理由のためにIDisposableを実装するので、私はこのような共有インスタンスに対してお勧めします。コメントで


UPDATE

、そのスクリプトを実行している実行しているタイマーがあることを示しています。タイマーの代わりに、タスクを実行するサイト上のWebサービスまたは所定のページを呼び出す予定タスクの設定をお勧めします。その後、常にHttpContextを使用して作業します。

+0

私は彼のHttpContextについて同じ考えを持っていましたが、スレッドを生成しているので、コンテキストはありません。 – JoshBerke

+0

@ Josh:これらのスクリプトを実行するためにスレッドを生成しているという兆候はありません。関数はglobal.aspxにあります。そのモジュールのイベントの標準セットである場合、それらはサーバーへの要求に応答して来ます。 – casperOne

+0

彼のコメントをチェックしてください。彼は、App_Startの間に定期的に実行されるいくつかのタイマーを持っていると言います。 – JoshBerke

0

HttpContext.Currentは静的メソッドであり、コードが要求のコンテキスト内で実行されている限り、どこからでも利用できます。

あなたがリクエストのコンテキスト内で実行していない場合は、Application.Cacheを使用して見ることができますが、DataContextを開いたままにしておくことには注意が必要です。私はエンティティへのlinqの非常にfamillarではないので、私は間違っている可能性がありますが、一般的に接続などのデータベース関連項目をキャッシュするのは悪いです。

また、ロジックをglobal.asaxからWindowsサービスに移動することをお勧めします。これにより、これらのタスクをより詳細に制御できるようになります。たとえば、Webサイトのseperatleyをシャットダウンすることができます。

編集

JSは、静的変数を使用できることを指摘しています。また、ThreadLocal属性でマークされたインスタンス変数を定義することもできます。これにより、各スレッドに変数のコピーが与えられ、競合が解消されます。あなたは、各スレッドがそれ自身のコピーをとにかく持っていることを望むからです。

0

これらは、他のDataContextと同じ方法で処理する必要がある理由はありますか?コンテキストがイベント処理ルーチンの内部でのみ必要な場合は、それを回避する必要はありません。特にApplication_Start(あなたのコメントによる)にあれば、どこにでもキャッシングする必要はありません。単にローカルで使用し、必要に応じて他のメソッドに渡します。

0

タイマーの作成時に、DataContextを状態パラメータとして設定します。コメントに投稿した情報に基づいて、あなたのDataContextは他のものよりタイマーに関連しているようです。

また、異なるタイマーからの変更が混在するため、異なるタイマーで同じDataContextを使用しないでください。同じタイマーロジックが2回実行されないようにしてください。同じタイマーロジックが制御されずに短すぎます。