4

アプリケーション自体は2000行の長さであるため、ここにコードを貼り付けるのは意味がありません。特に、受け取ったユーザーの1人が、コードのどの部分が問題を引き起こしているのかについてのヒントを与えないためです。

ちなみに、このアプリは、通常数百行以下のデータとその他のコントロールを表示するdatagridviewを備えた単なるWindowsフォームです。クラッシュする前は、datagridviewの各行のセルを非常にゆっくりとロードしていました。(しかし、他のユーザーが同じ問題を経験したことはありません。)

例外テキストは以下のとおりです。誰かがそれを確認して、私のコードが間違っていることが原因であるか、またはこの例外を経験したユーザーの特定の設定と互換性がないことが原因であるかどうかを教えてもらえますか?

以下の説明は、メモリが破損していることを示しています。ユーザーのコンピューターのRAMが不良であることを意味しますか?

  ************** Exception Text **************
  System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
     at System.Drawing.SafeNativeMethods.Gdip.GdipDrawRectangleI(HandleRef graphics, HandleRef pen, Int32 x, Int32 y, Int32 width, Int32 height)
     at System.Drawing.Graphics.DrawRectangle(Pen pen, Int32 x, Int32 y, Int32 width, Int32 height)
     at System.Windows.Forms.ControlPaint.DrawFlatCheckBox(Graphics graphics, Rectangle rectangle, Color foreground, Brush background, ButtonState state)
     at System.Windows.Forms.ControlPaint.DrawFlatCheckBox(Graphics graphics, Rectangle rectangle, ButtonState state)
     at System.Windows.Forms.ControlPaint.DrawCheckBox(Graphics graphics, Int32 x, Int32 y, Int32 width, Int32 height, ButtonState state)
     at System.Windows.Forms.ControlPaint.DrawCheckBox(Graphics graphics, Rectangle rectangle, ButtonState state)
     at System.Windows.Forms.CheckedListBox.OnDrawItem(DrawItemEventArgs e)
     at System.Windows.Forms.ListBox.WmReflectDrawItem(Message& m)
     at System.Windows.Forms.ListBox.WndProc(Message& m)
     at System.Windows.Forms.CheckedListBox.WndProc(Message& m)
     at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
     at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
     at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
4

2 に答える 2

5

これ以上のコードがなければ、正確に言うのは難しいです。ここに注意すべきことがいくつかあります。

.NETは管理された環境であり、その基本原則の1つは、コンパイル時にコードを検証する機能です。具体的には、これは、次のようなコードの単位について特定の保証が行われる可能性があることを意味します。

  • 配列の境界を超えて読み取ることができない
  • 関数ポインタを変更できない
  • メモリのコードセグメントを読み取ったり変更したりできない
  • オブジェクト参照のタイプを混同できない

これらを実行しようとすると、コンパイル時または実行時に例外が発生して失敗します。

あなたが見ている例外は、「安全でない」コードの結果として来ます。安全ではないというのは、実際には少し誤称です。「検証不能」と表現する方が適切です。場合によっては、パフォーマンス上の理由から、ポインター演算などによる生の速度と引き換えに、コードの検証可能性を放棄する必要があります。

このアプリには安全でないコードはありません。

WinFormsは、「安全でない」コードを多用します。アセンブリには安全でないコードは含まれていませんが、安全でないライブラリコードに依存していると言っても過言ではありません。

以下の説明は、メモリが破損していることを示しています。ユーザーのコンピューターのRAMが不良であることを意味しますか?

RAMが不良である可能性はありますが、ほとんどありません。存在すると予想される値が実際には存在しない場合、メモリは破損しています。これは、ハードウェア障害が原因である可能性がありますが、ソフトウェアエラーも原因である可能性があります。この例外は通常、私の経験ではソフトウェアエラーに応じて発生します。また、メッセージには、メモリ破損している可能性があることが示されています。

スタックトレースは、メモリが以前に破損している可能性があり、ここに表示されているスタックフレーム中にのみ検出されたため、実際にはあまり洞察に満ちていない可能性があります。

user32.dllのShowWindow関数(ShowWindow(p.MainWindowHandle、SW_SHOWDEFAULT);)へのプラットフォーム呼び出し呼び出しが1つありますが、この呼び出しはメッセージループが開始される前に行われます。

これが原因かもしれません。代わりにマネージドWindow.Showメソッドを使用してみましたか?ウィンドウにまだハンドルがないか、ウィンドウが変更されているか、これが原因で問題が発生した可能性があります。一般に、ネイティブのものの上にマネージラッパーを使用する場合は、PInvokeを回避するようにしてください。

残念ながら、コードをもっと見ることなく、より有用な答えを提供することは不可能ですが、うまくいけば、上記は例外のコンテキストを提供し、アプリケーションがWinFormsをこの状態にするために何をしているのかを知るのに役立つかもしれません。

于 2012-10-15T13:15:03.430 に答える
0

この例外が発生し、それを理解するのに数日かかったので、これについて言及したいと思います。上記の問題が関連しているかどうかはわかりませんが、上記の例外を探しに来る人に役立つかもしれません。

いくつかのロギングコードをテストしていましたが、テストがチェックインされると、ビルドサーバーに例外がポップアップ表示されます。開発マシンでローカルに再作成できませんでした。

ロジックをコンストラクターからメソッドに移動することにしましたが、突然、例外がSystem.EntryPointNotFoundExceptionに変更されました。

テストハーネスでは、ロガーによって参照されていないSystem.WebAPIを使用してオブジェクトを配置していました。適切なライブラリを参照すると、問題が修正されました。

TL; DR; この例外が発生した場合は、ビジネスロジックをCtorに入れて、参照を確認しないでください。

于 2014-10-31T15:34:44.350 に答える