28

非常に有線のエラーがあります。カスタムコントロールの1つは、2つのコンパイル済みファイルを作成しているようです。動的にロードしようとすると、LoadControl()まったく同じであっても、一方を他方にキャストできないため、失敗します。私はすべてが同じであることを確認するためにメッセージを書きます、コンパイルされたdllを変更するだけです。

System.Web.HttpUnhandledException (0x80004005):     
 Exception of type 'System.Web.HttpUnhandledException' was thrown. --->             
    System.InvalidCastException:
[A]ASP.Modules_OneProduct_MedioumImage cannot be cast to
[B]ASP.Modules_OneProduct_MedioumImage.         

   Type A originates from 'App_Web_kg4bazz1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'
in the context 'Default'
    at location 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\80ed7513\10eb08d9\App_Web_kg4bazz1.dll'.          

   Type B originates from 'App_Web_oneproduct_mediumimage.ascx.d1003923.4xoxco7b, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' 
in the context 'Default'    
    at location 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\80ed7513\10eb08d9\App_Web_oneproduct_mediumimage.ascx.d1003923.4xoxco7b.dll'.

コード

これは、 MSDNに書かれている内容を正確に実行した後の、現在のコードです。

foreach (int OneProductID in TheProductIdArrays)
{
    // here is the throw.
    ASP.Modules_OneProduct_MedioumImage OneProduct = 
        (ASP.Modules_OneProduct_MedioumImage)LoadControl(@"~/mod/OneProduct_MediumImage.ascx");

    // do some work with 
    //OneProduct
}

以前は、コントロールをロードせずにロードしましたASP.が、このバグが表示されて解決策を探した後、MSDNの内容に厳密に従います。私が何をしても、バグはまだここにあります。

私はまた、この方法の両方を、それぞれを単独で、そして一緒に(再び失敗して)試しました

<%@ Register src="~/mod/OneProduct_MediumImage.ascx" tagname="OneProduct_MediumImage" tagprefix="uc1" %>
<%@ Reference Control="~/mod/OneProduct_MediumImage.ascx" %>

構成

私のweb.configは、20、100、1000で試しましたが、trueまたはfalsemaxBatchSizeでも試しましoptimizeCompilationsたが、バグが再び発生します。

<compilation debug="false" defaultLanguage="C#" batch="true"
maxBatchSize="800" batchTimeout="10800" optimizeCompilations="false"
targetFramework="4.0">

今についてのいくつかの詳細

  • エラーはランダムであり、コンパイルが表示される場合と表示されない場合があります。
  • このプロジェクトは大きなもので、ページは毎分たくさんの人が何かを見ようと頼んでいるだけでなく、中に誰もいないときにも表示されます。
  • 64ビットdot.net4、統合で実行されます
  • Webガーデンとして実行しますが、テスト済みで1つのプールのみ(同じ問題が発生します)
  • プロジェクト全体でセッションがオフになっています。
  • ページは2007年から掲載されていますが、この問題は先月発生しました。残念ながら、どこでどのように開始されたのか、何が原因で発生したのかがわかりません。
  • カスタムコントロールロードが1つだけ表示され、呼び出しが多いものが表示されます。
  • コードを4倍変更して、小さな変更または大きな変更を加えましたが、まだそこにあります。
  • 私はoptimizeCompilations真と偽、そして同じ問題で試してみました。
  • また、Webを停止し、すべての一時ファイルを削除し、再度開いてみましたが、再び実行されました。
  • アプリケーションが一度に1つのコンパイルのみをロックし始めたときに、global.asaxにミューテックスを配置しようとしましたが、これも失敗します。
  • 動作した瞬間から、すべてが良好ですが、動作しない場合は自動修正されません。
  • このカスタムコントロールをロードするコードは存在し、コードの複数の場所、異なるページで呼び出されます。
  • 同様の負荷を持つ他のカスタムコントロールには問題はありませんでした。
  • このカスタムコントロールでは、ViewStateは無効になっています。
  • また、いくつかのコードを再配置し、マイクロオプティマイズで完全な関数呼び出しを変更してみましたが、失敗することはありません。
  • 開発用コンピュータで問題なく動作します。web.configに配置batch="true"すると、バグがすぐに表示されます。
  • どうしても直せないバグなど、他にそのような問題はありません。システムは数日間稼働し、プールはまったくリサイクルされておらず、メモリは安定しており、より多くの空き容量があります。プログラムは何年も実行されていますが、私たちはほぼ毎日更新されて変更されます。
  • 同じコアコードの下で複数のサイト(stackexchangeのようなもの)が実行され、すべてが同じランダムな問題を抱えています。
  • AutoEventWireupがfalse
  • それが表示され、同じ方法でロードする他のカスタムコントロールに表示されます。

このバグが発生した場合の回避策として、現在行っていること:小さな変更を加えてプロジェクトを強制的に再コンパイルすると、次の更新までエラーがなくなります。

理由を見つけることなく、過去数週間のツリーを解決しようとするバグがあります。できることはほとんど何でも試しましたが、すべて失敗し、バグが再び発生します。だから私はここに投稿するかもしれませんが、私を助けてこれから抜け出す方法を見つけることができるかもしれません。

最後の言葉:このバグはおかしいです、カスタムコントロールは同じです、私はそれに対して何でもします私はそれを動的にロードしてブームします、コンパイラは彼だけが知っている何らかの理由でそれを2つの異なる時間に持っています-ランダムに。

アップデート1

開発者のマシンでバグを再現することができました。そこで、このカスタムコントロールを含む2つのdllモジュールが異なることに気付きました。

1つは、4つのカスタムコントロールをまとめたものです。もう1つのモジュールは、カスタムコントロールのみでした。

回避策

ツリー週間でこのバグを修正しようとした後、コンパイラがディレクトリのバッチコンパイルを行い、同じdllに多くの異なるカスタムコントロールをバンドルすると、このバグが発生することになります。したがって、単独でロードしようとすると、この例外がスローされます。

そのため、問題のあるカスタムコントロールを別のディレクトリだけに移動し、今のところ回避しているようです。

アップデート2

一部のファイルを別のディレクトリに移動した後でも、再び表示されます。ランダムであり、そのトリガーとなるものとの明確な関係を見つけることができません。

アップデート3

ここでの主な問題はbatch="true"、同じdllで多くのカスタムコントロールをコンパイルするバッチコンパイル()であることがわかっているため、コンパイラにそれを行わないように指示する1つの方法はmaxBatchGeneratedFileSizeパラメータです。100の値で使用しましたが、問題が再び発生しました。今度は40に下げてテストします。

maxBatchGeneratedFileSize="40"
4

5 に答える 5

11

これは、バッチ処理がオンになっていて、ディレクトリレベルで何らかの形の循環参照がある場合に発生する可能性があります。

意味は非常に微妙なので、この文脈での「循環参照」の意味を正確に理解するには、この回答を参照してください。

サイクルを中断することができた場合(たとえば、ユーザーコントロールを別の場所に移動した場合)、この問題は発生しません。

アップデート1

理論的には、これはサイクルによってのみ引き起こされると思いますが、検出が難しい場合もあります。

私はあなたに私がうまくいくと思う代替の解決策をあなたに与えるでしょう、そしてそれは(それは少しハックですが)非常に簡単に試すことができます。問題を引き起こしているユーザーコントロールで、ディレクティブに次の属性を追加します。

<%@ Control Language="C#" [...] CompilerOptions="/define:dummy1" %>

他のいくつかのコントロールでこれを見る場合は、同じものを追加できますが、dummy2、dummy3などを使用します...

これは、他のユーザーコントロールとはコンパイルのニーズが異なるため、この1つのユーザーコントロールをバッチ処理しないという効果があります。技術的には、C#コマンドラインの任意の部分をとして追加できますCompilerOptionsが、ダミー/defineが最も単純で最も無害です。

ただし、バッチ処理をグローバルにオフにするのとは異なり、ページの非常に小さなサブセットのみがバッチ処理されないため、パフォーマンスへの影響は最小限に抑えられます。

ところで、あなたが見ているのはASP.NETのバグであり、そのバグはおそらく10年以上続いていることは言うまでもありません。多分ある時点でそれは対処されるべきです:)

于 2013-03-06T17:13:46.830 に答える
2

問題の原因を追跡するには、コントロールがどのように作成されたかを知ることが重要だと思います。この読み物を参照してください:.ascxユーザーコントロールを再配布可能なカスタムコントロールに変える

ステップ1:ユーザーコントロールを作成する

ユーザーコントロールを作成するには、ascx以外のものを含まない空のアプリから始めるのが最善です。ユーザーコントロールの作成には「標準」の手法が使用されますが、スタンドアロンのカスタムコントロールに正常に変換するには、いくつかの制限に注意する必要があります。 主な制限は、ユーザーコントロールが自己完結型である必要があるということです。つまり、App_Codeやglobal.asaxなどのアプリのグローバルなものに依存することはできません。これは、UserControlをスタンドアロンDLLに変換することが目的であるため、そのDLLの一部ではないコードに依存している場合、他のアプリで機能しなくなるためです。。このルールの1つの例外は、UserControlがbinディレクトリ(またはGAC)にあるアセンブリに依存する可能性があることです。他のアプリでカスタムコントロールを使用するときは、他のアセンブリが常に利用可能であることを確認する必要があります。

ステップ3:Publishコマンドを使用してサイトをプリコンパイルします

(...)[固定の名前付けと単一ページのアセンブリを使用する]を選択します。これにより、ユーザーコントロールがascxファイルに基づく名前を持つ単一のアセンブリにコンパイルされることが保証されます。このオプションをチェックしないと、ユーザーコントロールが他のページやユーザーコントロール(ある場合)と一緒にコンパイルされる可能性があり、アセンブリは操作がより困難になるランダムな名前を受け取ります。

私の意見では、ユーザーコントロールがコンパイルされ、GACに個別のアセンブリとして登録され、WebアプリケーションDLLにも含まれている可能性があります。

注:これはコメントであるはずですが、前述のリンクからの引用を含めたかったのです。お役に立てば幸いです。

于 2013-03-07T09:46:51.267 に答える
1

アップグレードされたASP.NETWebサイトで多くのデバッグを行った後、私の最後のバグは実行時のバグでした。

ビルド/公開オプション「固定の名前付けと単一ページのアセンブリを使用する」をチェックしたところ、私のケースは解決しました:)

ここにいくつかの便利なリンクがあります:https ://msdn.microsoft.com/en-us/library/hh475319(v = vs.110).aspx

https://msdn.microsoft.com/en-us/library/aa479044.aspx

http://forums.asp.net/t/960707.aspx

于 2016-02-14T23:43:25.173 に答える
0

最近、asp.net MVC 4の修正バージョンをコンパイルし、新しいDLLをプロジェクトにインポートしているときに、同様の問題が発生しました。

どういうわけか、web.config内の古いバージョンのDLLを参照していました(viewsフォルダー内のweb.configを含む)

私の場合、2つのDLLのバージョンが異なるため、エラーがスローされました。4.0.0および4.1.0。多分あなたはそれを調べるべきです。たぶんコンパイルされたファイルのバージョンを指定します(私はDLLを推測しています)

これが問題の解決に役立つことを願っています。

その他のヒント:ある種のバージョン管理システムがあると思いますか?はいの場合、これを開始する前にすべての変更を元に戻し、コードと、どのモデル/コントロールがどのように変更されるかを注意深く確認します。VCSを使用していない場合...変更を元に戻すためにできることはあまりありません。そして、VCSの使用を開始する必要があります。

于 2013-03-04T22:51:55.757 に答える
0

デザイナーが2番目のCodeBehindデザイナーファイルを作成することがあることに気づきました。たとえば、次のようになります。

OneProduct_MediumImage.ascx
OneProduct_MediumImage.ascx.cs
OneProduct_MediumImage.ascx.designer.cs
OneProduct_MediumImage.ascx.designer1.cs

ソリューションエクスプローラーに[すべてのファイルを表示]オプションが設定されていない場合は気付かないでしょうが、Webプロジェクトの場合、コンパイラーはプロジェクトに含まれているファイルだけでなく、フォルダー内のすべてのファイルをコンパイルします。

次に、プロジェクトが「Webサイトプロジェクト」の場合、名前空間がないため、多くの奇妙なエラーが発生する可能性があります。このSOの質問を見てください:名前空間の問題.net

ClassName最後に、制御ファイルに属性を設定することで、ランダムに見えるUserControlエラーを解決することができました。例:

<%@ Control Language="cs" 
    AutoEventWireup="false" 
    CodeBehind="OneProduct_MediumImage.ascx.cs" 
    Inherits="ASP.Modules_OneProduct_MedioumImage"
    ClassName="OneProduct_MediumImageControl" %>
于 2013-03-07T09:04:56.553 に答える