ユーザーはページその後、ページのレンダリング、半ダースのスレッドを生成spawn.aspxすべてのASP.Netは一見のユーザーに送信しているという事実を心配しないでください使用のHttpContextは、スレッド間で
((System.Web.IHttpHandler)instance).ProcessRequest(reference to spawn's HTTPContext);
を使用してのヒット1つの要求に対する7つの応答、その部分が処理され、1つの応答のみが送信されます。
System.IndexOutOfRangeException at System.collections.ArrayList.Add at System.Web.ResponseDependencyList.AddDependencies(String[] items, String argname, Boolean cloneArray, DateTime utcDepTime) at System.Web.ResponseDependencyList.AddDependencies(String[] items, String argname, Boolean cloneArray, String requestVritualPath) at System.Web.UI.Page.AddWrappedFileDependencies(Object virtualFileDependencies) at ASP.spawned_page_no_1_aspx.FrameworkInitialize() at System.Web.UI.Page.ProcessRequest
我々は他の場所でそれを複製することはできません。
は問題があり、多くのスレッド(クワッドクワッド)と高トラフィック的環境(当社の生産的環境)で、私たちはエラーが発生します。私の同僚は、元のHTTPContextを再利用して他のスレッドに渡し、スレッドセーフではないため、これが原因だと考えています。
このロジックに続いて、新しいHTTPContextをスレッドに渡すように試みました。しかし、その部分は一見「結合」しません。具体的には、Sessionオブジェクトを新しいHTTPContextに取得する必要があります。私は、キャッシュのように他の部品も手に入れたいと思っています。レコードのHTTPContext.Current.Session.IsSynchronizedはfalseです。
私の質問は以下のとおりです。
- エラーがスレッド間のHttpContextを使用してからだと思いますか?
- どうすれば修正できますか?
- 修正によって各スレッドのHTTPContextが複製されている場合、どのように新しいものにSession(およびCache)を取得できますか?要求と応答はctorに入っていますが、セッションは設定できません。
編集:詳細を
だから戻って、この声明に行く:「ASP.Netは一見、ユーザ1つの要求のための7つのレスポンスを送信していますが、その部分が処理されていることを心配しないでください1つの応答のみが送信されます。レイモンド・チェンの巨大なファン、私はあなたに同意する: "今あなたは2つの問題がある"は、それ以上の情報がない場合、合理的な声明です。
実際に起こっていることは、返信するExcelドキュメントを作成していることです。 spawn.aspxページでは、それが優れたレンダリングであること、レンダリングを行うオブジェクトなど、いくつかの状態情報を設定しています。スポーンされた各ページはその情報を取得し、オブジェクトにレンダリングする順番になるまでブロックします。文字通り、このようになります場合:
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
if (this.RenderToExcel)
{
Deadlocker.SpinUntilCurrent(DeadLockToken);
RenderReport(this, this.XLSWriter);
Deadlocker.Remove(DeadLockToken);
}
else
base.Render(writer);
}
しかし、すべてのそれまでの処理 - データベースアクセス、制御階層構造、すべてのことが並行して行われます。そして、たくさんのことがあります。レンダリングでそれをブロックさせながら、それをparrallizeすれば、全体の時間が半分になります。
そして、Excelのレンダリングには何も書き直す必要はありません。すべてのコントロールは自分自身を優れたものにする方法を知っていて、独立した各ページを個別に訪問することができます(実際には正常なケース - 実際にはすべてのスポンサーページの集合です)。 「あなたはこれを行うことはできません。アプローチを再考する必要があります」 - しかし、少なくとも論理的にもコードも複製したり、抽象化することなくすべてがうまく動作するという事実ちょうど完璧です。そして、それが問題であるだけのマルチスレッドです。すべてのページを連続的にレンダリングすれば、すべてがうまく、遅くなります。
Alこのロックはおそらく手配するのが難しいでしょう。彼が得ているスレッド例外は、これを行っているページのアクションをオーバーライドできない限り、httpコンテキストを変更しているページクラスからですロックソリューションは動作しません。 – meandmycode
素晴らしいコメント、私はあなたに同意します。私の好みは、トレッドの作成時にHTTPコンテキストからその情報の一部を派生させる完全に新しいオブジェクトを渡すことです。それは弾丸であろう。 –