76

私は、「他のすべてが失敗した場合にそれをキャッチする」ことが最善の方法であると思っています。

つまり、アプリケーションで可能な限り多くの例外を処理していますが、それでもバグが発生する可能性があるため、未処理の例外をすべてキャッチして、情報を収集してデータベースに保存したり送信したりできるようにする必要があります。 Web サービスに。

AppDomain.CurrentDomain.UnhandledException イベントはすべてをキャプチャしますか? アプリケーションがマルチスレッドであっても?

補足: Windows Vista は、クラッシュ後に任意のアプリケーションが自身を回復できるようにするネイティブ API 関数を公開しています...名前は今は思いつきません...しかし、多くのユーザーがまだ使用しているため、使用したくありません。 WindowsXP.

4

9 に答える 9

18

ASP.NET ではApplication_Error、ファイル内の関数を使用しGlobal.asaxます。

WinForms ではMyApplication_UnhandledExceptionApplicationEventsファイルで を使用します。

これらの関数は両方とも、コードで未処理の例外が発生した場合に呼び出されます。これらの関数から、例外をログに記録し、ユーザーに適切なメッセージを表示できます。

于 2008-10-20T19:39:07.303 に答える
13

Winform アプリケーションの場合、AppDomain.CurrentDomain.UnhandledException に加えて、Application.ThreadExceptionApplication.SetUnhandledExceptionMode (w/ UnhandledExceptionMode.CatchException) も使用します。この組み合わせはすべてをキャッチするようです。

于 2008-10-20T19:48:48.813 に答える
6

メインスレッドでは、次のオプションがあります。

他のスレッドの場合:

  • セカンダリ スレッドには未処理の例外はありません。SafeThreadを使用する
  • ワーカー スレッド: (タイマー、スレッドプール) セーフティ ネットはまったくありません!

これらのイベントは例外を処理せず、単にアプリケーションに報告するだけであることに注意してください。多くの場合、それらについて有用な/正気なことを行うには遅すぎる場合があります。

例外をログに記録するのは良いことですが、アプリケーションを監視する方が優れています ;-)

警告: 私はSafeThread記事の著者です。

于 2008-10-20T20:06:59.167 に答える
4

WinForms の場合、現在のスレッドの未処理の例外イベントにもアタッチすることを忘れないでください (特にマルチスレッドを使用している場合)。

ベスト プラクティスに関するいくつかのリンクはこちらこちらこちらです (おそらく .net の例外処理に関する記事としては最適です)。

于 2008-10-20T19:47:47.987 に答える
2

マルチスレッド アプリでもそのハンドラーでほとんどの例外を監視できますが、.NET (2.0 以降) では、1.1 互換モードを有効にしない限り、未処理の例外をキャンセルすることはできません。その場合、AppDomain は何があってもシャットダウンされます。最善の方法は、別の AppDomain でアプリを起動して、この例外を処理し、新しい AppDomain を作成してアプリを再起動できるようにすることです。

于 2008-10-20T21:51:41.107 に答える
2

There's also a cool thing called ELMAH that will log any ASP.NET errors that occur in a web application. I know you're asking about a Winform App solution, but I felt this could be beneficial to anyone needing this type of thing on a web app. We use it where I work and it's been very helpful in debugging (especially on production servers!)

Here's some features that it has (pulled right off the page):

  • Logging of nearly all unhandled exceptions.
  • A web page to remotely view the entire log of recoded exceptions.
  • A web page to remotely view the full details of any one logged exception.
  • In many cases, you can review the original yellow screen of death that ASP.NET generated for a given exception, even with customErrors mode turned off.
  • An e-mail notification of each error at the time it occurs.
  • An RSS feed of the last 15 errors from the log.
  • A number of backing storage implementations for the log, including in-memory, Microsoft SQL Server and several contributed by the community.
于 2008-10-20T21:08:04.503 に答える
0

マネージド GUI アプリでは、デフォルトで、GUI スレッドで発生した例外は、Application.ThreadException に割り当てられたものによって処理されます。

他のスレッドで発生した例外は、AppDomain.CurrentDomain.UnhandledException によって処理されます。

GUI スレッドの例外を非 GUI のものと同じように機能させて、AppDomain.CurrentDomain.UnhandledException によって処理されるようにする場合は、次のようにします。

Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);

ThreadException を使用して GUI スレッドの例外をキャッチする利点は、アプリケーションを続行させるオプションをユーザーに提供できることです。構成ファイルがデフォルトの動作を上書きしていないことを確認するには、次を呼び出すことができます。

Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

動作の悪いネイティブ dll からの例外に対しては、依然として脆弱です。ネイティブ dll が Win32 SetUnhandledExceptionFilter を使用して独自のハンドラーをインストールする場合、以前のフィルターへのポインターを保存し、それも呼び出す必要があります。そうしないと、ハンドラは呼び出されません。

于 2009-09-26T23:01:12.383 に答える
0

私は次のアプローチを使用しています。これは機能し、コードの量を大幅に削減します(ただし、より良い方法があるかどうか、またはその落とし穴が何であるかはわかりません。電話するたびに:マイナスを与える質問は礼儀正しいでしょう。彼らの行動を明確にするのに十分です;)

try 
{
    CallTheCodeThatMightThrowException()
 }
catch (Exception ex)
{
    System.Diagnostics.StackTrace st = new System.Diagnostics.StackTrace ();
    Utils.ErrorHandler.Trap ( ref objUser, st, ex );
} //eof catch

そしてここに ErrorHandler コードがあります:ロギング アクティビティの実行 StackTrace st - アプリのデバッグ情報を提供する StackTrace オブジェクト

using System;
using log4net; //or another logging platform

namespace GenApp.Utils
{
  public class ErrorHandler
  {
    public static void Trap ( Bo.User objUser, ILog logger, System.Diagnostics.StackTrace st, Exception ex )
    {
      if (ex is NullReferenceException)
      { 
      //do stuff for this ex type
      } //eof if

      if (ex is System.InvalidOperationException) 
      {
        //do stuff for this ex type
      } //eof if

      if (ex is System.IndexOutOfRangeException) 
      {
        //do stuff for this ex type
      } //eof if

      if (ex is System.Data.SqlClient.SqlException)
      {
        //do stuff for this ex type
      } //eof if

      if (ex is System.FormatException)
      {
        //do stuff for this ex type
      } //eof if

      if (ex is Exception)
      {
        //do stuff for this ex type
      } //eof catch

    } //eof method 

  }//eof class 
} //eof namesp
于 2009-05-20T08:47:00.300 に答える