エクスポート (0) 印刷
すべて展開
この記事は翻訳者によって翻訳されたものです。 記事の文章にポインターを重ねると、原文のテキストが表示されます。
訳文
原文

エラー処理

Silverlight

Silverlight のマネージ API には、アプリケーション コードを処理するランタイムをラップする、エラー処理と例外処理のマネージ層があります。 アプリケーションのユーザー コードで発生した例外を処理するには、UnhandledException のハンドラーを登録します。 プラットフォーム コードの例外および UnhandledException で処理しないように選択した例外は、Silverlight プラグインのネイティブまたはアンマネージのエラー機構に渡されます。 このレベルでは、プラグインのインスタンス化中に指定した OnError ハンドラーを使用してエラーを処理できます。 発生したエラーや例外によっては、Silverlight に対するコーディングやスクリプトの処理がそれ以上行われない場合もあれば、重大と見なされずにアプリケーションに対するコーディングやスクリプトの処理を続行できる場合もあります。 このトピックでは、エラー処理の概念、API、および Silverlight での一般的なエラーと例外の処理に関連する技術について説明します。

このトピックには次のセクションが含まれています。

アーキテクチャの観点から言うと、Silverlight はアプリケーション コードを実行するランタイムです。 Silverlight ランタイムの大部分は、ネイティブ コードとして内部的に実装されています。 このアーキテクチャは、主に次の 3 つの理由から採用されています。

  • Silverlight のランタイムは、ブラウザー ホスト スクリプト モデル (Silverlight 1.0 の時のアプリケーションで使用可能な元のモデル) もサポートするコアに基づいています。

  • ランタイムそのものが、ネイティブ コードから基本 CLR エンジンまたはランタイムを実装する必要があります (特に Macintosh 上で Silverlight を使用する場合)。

  • Silverlight での XAML 解析の一部は、ネイティブ コード実装を使用して行われます。

このように、Silverlight のマネージ API は、多くの場合、Silverlight のコア ネイティブ関数の Thin ラッパー、または初期の Silverlight 専用 CLR ランタイムおよびライブラリに基づいたマネージ コードです。

Silverlight のマネージ API は、例外を発生させることができます。 通常、特定の API でその特定のクラスの主な例外として発生する例外は、Silverlight リファレンス トピックの .NET Framework クラス ライブラリで説明されています。 これらがラッパーの場合、マネージ API アクションによってネイティブ レベルのエラーが発生します。 場合によっては、ラッパーからの UnhandledException によってネイティブ エラーが表されます。 しかし、例外が発生することなくエラーが発生する場合もあります。また、Silverlight ランタイムがシャットダウンすることもあります。

詳細については、Silverlight のアーキテクチャ のトピックを参照してください。

一般に、マネージ コードが扱うのは、エラーではなく例外です。 ただし、既に「例外、エラーおよび Silverlight のアーキテクチャ」のセクションでも説明したように、Silverlight にはネイティブ コアが使用されています。このトピックでは、以降、"エラー" という言葉はネイティブ コードによって報告されたエラー状況を指すものとします。 また、Silverlight ランタイムでは、プラットフォームから発生した例外とアプリケーション コードから発生した例外とが区別されます。

マネージ プログラミングに慣れておらず、例外のしくみの詳細を知りたい場合は、「例外の処理とスロー」を参照してください。

例外には、その例外の Message プロパティ値の一部として情報が含まれていることがよくあります。 この情報は、実際に、アプリケーションの開発中のみに使用されることを意図しています。 Message として報告される正確な文字列は変わる可能性があるので、実際の配置済みのアプリケーションの動作では、これに依存するべきではありません。 特に、Silverlight ライブラリのデバッグ バージョンには、同じ Silverlight アプリケーションを実行する標準のエンド ユーザー ランタイムに表示されない、メッセージ内の追加情報が含まれています。 例外メッセージの固定部分は、多くの場合、ライブラリ内のリソースとして含まれ、スローされるときに実行時例外によって参照されます。 コンテキストによって例外メッセージの他の部分 (例外クラスの特定のプロパティ値を含む) を渡すことができます。

プラットフォームの例外とアプリケーションの例外

Silverlight のエラー/例外システムでは、プラットフォーム例外 (Silverlight そのものの .NET ライブラリおよびコア ランタイム用に実装された API に関連した例外) と、コア ランタイムでアプリケーションのコードを実行した結果として発生した例外とが区別されます。 プラットフォームの例外はまれにしか発生しませんが、発生した場合には、一般的に、Silverlight コアが停止し回復不能になります。

アプリケーション コードで発生したマネージ例外の処理では、例外の中央の処理ポイントとして Application を使用します。 アプリケーション全体に対応する単一の UnhandledException ハンドラーを作成します。

UnhandledException ハンドラー内で、通常、最も興味深い情報は ExceptionObject です。 このプロパティは発生した特定の例外を報告し、デバッガーがアタッチされている場合には、デバッガーに報告される例外に対応します。 例外オブジェクトで GetType() を呼び出し、その型を使用して、発生した例外に基づいて別のコード パスに切り替えることができます。 この手法は、このトピックの次のセクションで説明するように、アプリケーションの製品版の実行時シナリオで、回復することができる可能性がある例外を分離するのに役立ちます。

例外処理をより小さなモジュールに分割する手法や、特定の呼び出しの特定の例外をキャッチする手法として、固有の try/catch ブロックを作成することもできます。 場合によっては、例外を修正する方法にとってより適したコンテキストが得られるため、特定の例外処理シナリオでは、固有の try/catch を使用するのが最適な手法です。 例外をキャッチする固有の try/catch がアプリケーション コードに記述されている場合、Application.UnhandledException は呼び出されません。 ただし、アプリケーションの try/catch で特定の例外がキャッチされない場合は、Application.UnhandledException が呼び出されます。

開発プロセス中に発生する例外

アプリケーションの開発期間に Visual Studio を使用して開発を行うと、Silverlight の初回例外で中断できます。 これは、その例外が回復不能で、Silverlight のコア プロセスの停止かアプリケーション ドメインのアンロードが必ず実行される場合であっても可能です。

通常、XAML 解析で発生する例外はアプリケーションを機能させるために回復不能であるため、結果として得られる XamlParseException で中断できます。 イベント データに示されている行情報を調べることで、解析に失敗したマークアップ要素または属性を特定できます。 Silverlight での XAML 解析では、本質的に、最初に解析の問題のみが報告されます。このため、初回のエラーを修正して再度解析を実行した場合、同じ XAML ファイルで構文的なエラーが明らかになる場合があります。

Visual Studio を使用する場合に、初回例外での中断が必ずしも実行できない例として、object タグなどの手法を使用する Silverlight プラグインの初期化があります。 これらの種類のエラーはホスト (一般的にブラウザー ホスト) のドメイン内で発生するため、Visual Studio でアクセスして初回例外での中断に使用できるサービスで必ず公開されているとは限りません。

Visual Studio の既定の Silverlight プロジェクト テンプレートでは、既定の UnhandledExceptionEventHandler 実装が app.xaml.cs ファイルまたは app.xaml.vb ファイル内に生成されます。 この特別な UnhandledException ハンドラーを使用すると、アプリケーションを停止することなく、ブラウザー ホストで発生するマネージ例外を把握できるため、開発フェーズで役立ちます。 これは、処理した例外にマークを付け、ブラウザー DOM を使用してメッセージ ボックスに例外を表示することにより実現されます。 したがって、デバッグに Visual Studio を使用できないプラットフォームやホスト上で、例外情報を表示できます。 このハンドラーを実装した状態でアプリケーションを配置しないでください。 その代わり、次のセクションで説明するように、配置用の UnhandledException ハンドラーで必要に応じて例外をログに記録し、回復可能な例外のみを処理する必要があります。

デザイン時のレイアウト例外

Silverlight の一部のレイアウト例外には、デザイン ツールに特別なデザイン時処理があります。このため、Silverlight ランタイムがデザイン画面内でシャットダウンすることなく、問題を修正するためのガイダンスがツールによって示されます。 このようなレイアウトの問題の例として、無限の desiredSize を返す Measure パス、レイアウト サイクル、デザイナーによる無効なビジュアル ツリーになるようなテンプレートの拡張などがあります。 このような問題は、デザインと開発の段階で必ず修正してください。 デザイン モードではなく実行コードでこれらの同じ問題が引き続き発生する場合、回復不可能な例外であることがほとんどです。

回復可能な例外と回復不能な例外

どの例外を回復可能な例外とするかという決定は、部分的に、UnhandledException ハンドラーの作成方法によって制御されます。 特定の例外を回復可能なものにすると決定し、その例外の処理をそれ以上行う必要がない場合、イベント データの Handledtrue に設定します。 例外からの回復とは、別のコード パスの入力、別の UI の表示、アプリケーション固有の状態の分離ストレージへの保存 (この状態を後でアプリケーションを再起動するときに使用できるように)、アプリケーション シナリオに固有のその他の処理を意味します。

イベント データの Handledtrue に設定しない場合、例外はエラー処理のアンマネージ レベルになります。 これは、スクリプトで作成し、ブラウザー スクリプト ホストで実行する onError ハンドラーで処理できる可能性があります。 ただし、例外がこの状況になると、アプリケーションの AppDomain が終了しているため、マネージ アプリケーション コードを実行することはできません。

メモ メモ :

相互運用や初期配置に関連したシナリオなど、場合によっては、エラーをスクリプト処理にまで落下させて、onError で処理した方がよいケースもあります。 しかし、ほとんどの場合、回復可能なエラーを UnhandledException ハンドラーで処理するように指定する必要があります。

詳細については、「UnhandledException」と、「アプリケーション サービス」の「未処理の例外処理」を参照してください。

サービス例外

開発段階で Silverlight サービスをデバッグする場合、テスト クライアントとやり取りするトランスポート レベル情報をチェックする技術、運用ドメインではなくテスト ドメインを使用してサービスとサービス要求を再構成する技術などが必要となります。 多くの場合、サーバーの例外を有効にするのに便利です。 詳細については、「Silverlight アプリケーションのサービスのデバッグ」を参照してください。

Silverlight アプリケーションを展開すると、サービスにアクセスしようとするすべてのアプリケーションは、サービスが使用できない場合や有効な応答を返すことができない場合にも、正常に動作します。 クライアントは、サーバー上のクライアント アクセス ポリシーがサービスへのアクセスを拒否する場合も適切に処理します。

Silverlight 4 以降を対象としている場合は、WCF SOAP フォールト プログラミング モデルを使用して、クライアント上の実稼働用の宣言されたフォールトとデバッグ用の宣言されていないフォールトを処理できます。 WCF SOAP フォールト プログラミング モデルを使用するには、200 番台のステータス コードでエラーを配信するサービスを構成するか、サービス通信のための代替クライアント HTTP スタックを登録する必要があります。 詳細については、「Silverlight でのエラーの作成と処理」を参照してください。

データ検証エラーと例外

いくつかのケースでは、デバッグ環境でアプリケーションを実行している場合に、実行時データ検証を使用しているプロパティで検証コードの実行前に例外が発生することがあります。 Visual Studio では、[デバッグ] メニューの [例外] を選択し、CLR 例外の一部またはすべての動作を変更することで、例外処理動作を変更できます。 データ検証を例外に関連付ける方法の詳細については、「データ バインディング」を参照してください。

バックグラウンド スレッド

Silverlight で実行しているバックグラウンド スレッドで発生する例外は、UnhandledException に昇格されません。

XAML 解析エラー

通常、XAML パーサー エラーは、配置されたアプリケーションの UnhandledException 処理として処理できる可能性があるエラーではありません。 このような XAML パーサー エラーは、アプリケーションの開発フェーズ中に検出する必要があります。 詳細については、Silverlight XAML のデバッグ のトピックを参照してください。

ただし、実行時に XamlReader.Load を使用して XAML を読み取る場合に、XAML として読み込む文字列ソースが、文字列解析、XML フラグメント、分離ストレージ、データベース レコードなど、XAML ソース全体を完全にテストするハンドラーであるソースを使用して構築されていると、実行時にパーサー エラーが発生する可能性もあります。 もう 1 つの原因として、Silverlight コア セットのものではないアセンブリによってサポートされる型を参照している場合に、Silverlight の展開の一部としてそのアセンブリをパッケージ化していないということが考えられます。 これにより、クライアントから見るとアセンブリが実行時に存在しないことになり、XAML パーサー エラーに欠落したアセンブリの問題を明らかにする方法が示される場合があります。

メモ メモ :

ユーザーまたはその他のエンティティに、XamlReader.Load 入力として使用される任意の文字列の指定を許可しないでください。 これは、エラーを防止するためだけではありません。検証されていない任意の XAML を読み込むと、アプリケーションのセキュリティにも大きく関係してきます。 XamlReader.Load の使用」の「XAML からのオブジェクト作成でのセキュリティに関する注意事項」を参照してください。

非同期メソッド イベント

UnhandledException を使用する手法では、失敗したダウンロード要求などの非同期操作で発生した例外をキャプチャできません。 一般的に、これらの例外は、元の非同期操作を呼び出すオブジェクトの専用ハンドラーで処理します。 専用のハンドラーがアタッチされていないとしても、このような場合に UnhandledException ハンドラーは呼び出されません。

たとえば、イメージ ソースを URI で設定し、URI (イメージ) の読み込みエラーが発生する可能性があることがアプリケーションの設計で想定されている場合、通常は、ImageFailed 用のハンドラーを用意して、その特定の Image オブジェクトにアタッチします。 ハンドラーを用意しなければ、イメージの読み込みが失敗し、そのイメージのランタイム UI レイアウトが空白で表示されます (高さや幅を指定していなければ、サイズが 0 x 0 になる可能性もあります)。 このような状況でもアプリケーションは動作でき、UnhandledException イベントは発生しません。

Silverlight ベースのスクリプト アプリケーションでは、エラーの種類に応じて、JavaScript レベルでさまざまな方法を使用してエラーを処理できます。 Silverlight プラグインの OnError ハンドラーを使用すると、パーサー エラーや実行時エラーなど、各種のエラーを処理できます。 同期メソッド呼び出しを try/catch ブロックで囲むことにより、その呼び出しから発生したエラーを catch ブロックで処理できます。 MediaFailed などの非同期のエラー イベントにはイベント ハンドラーをアタッチできます。 Visual Studio でスクリプトのデバッグを有効にしている場合は、JavaScript 統合デバッグ サポート機能を使って、ブレークポイントを設定し、値を調べることができます。

メモ メモ :

Silverlight のドキュメントでは、特定のエラー メッセージについて取り上げることはしません。 詳細については、「Silverlight プラグインのエラー メッセージ」を参照してください。

OnError イベント ハンドラーの定義

Silverlight ベースのアプリケーションでは、Silverlight プラグインのオブジェクト要素の OnError パラメーターに、カスタムのイベント ハンドラー関数を設定してエラー ハンドラーを定義できます。

onError ハンドラーは、sender オブジェクトとイベント データの 2 つのパラメーターを受け取ります。 sender オブジェクトはエラーが発生したオブジェクトです。これは必ずプラグイン インスタンスで、オブジェクト ツリーの特定のオブジェクトを報告することはありません。 2 つ目のパラメーターは、ErrorEventArgs オブジェクトまたはその派生オブジェクト (ParserErrorEventArgs または RuntimeErrorEventArgs) のインスタンスです。 JavaScript はプロトタイプ ベースであるため、これらのすべてのエラーに対して使用できる errorType を判断してから、その errorType に一致する eventargs に基づいて、特定の種類のエラー イベント データのプロパティを照会できます。

次の表は、ErrorEventArgs オブジェクトのプロパティの一覧です。 これらのプロパティは、onError によって処理されるすべてのエラー イベントに共通です。

プロパティ

説明

errorMessage

エラー イベントに関連付けられたメッセージ。

errorType

エラーの種類 (ErrorType 列挙値として定義される)。

errorCode

エラー イベントに関連付けられた数値コード。

次の表は、パーサー エラーに固有のプロパティの一覧です。これらのプロパティは、ParserErrorEventArgs オブジェクトで定義されます。

プロパティ

説明

charPosition

エラーが発生した文字位置。

lineNumber

エラーが発生した行。

xamlFile

エラーが発生した XAML ファイル。

xmlAttribute

使用しないでください。

xmlElement

使用しないでください。

次の表は、実行時エラーに固有のプロパティの一覧です。これらのプロパティは、RuntimeErrorEventArgs オブジェクトで定義されます。

プロパティ

説明

charPosition

エラーが発生した文字位置。

lineNumber

エラーが発生した行。

methodName

エラーに関連付けられたメソッド。

次の例では、ブラウザー ホスト内の Silverlight ベースのアプリケーションで、object タグの宣言の一部として OnErrorEventHandler という名前のユーザー定義関数を OnError イベント ハンドラーとして設定します。

<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" ...>
  <param name="source" value="silverlightapplication1.xap"/>
  <param name="onerror" value="OnErrorEventHandler"/>
...
</object>

次の JavaScript の例は、Silverlight プラグインの OnError イベントに関連付けられたイベント ハンドラー関数を示しています。 ErrorEventArgs ErrorType プロパティを確認することによって、エラーの種類を判別します。 エラーが実行時エラーまたはパーサー エラーであった場合は、表示メッセージに補足的なエラー情報が追加されます。

function OnErrorEventHandler(sender, errorArgs)
{
    // The error message to display.
    var errorMsg = "Silverlight Error: \n\n";
    
    // Error information common to all errors.
    errorMsg += "Error Type:    " + errorArgs.errorType + "\n";
    errorMsg += "Error Message: " + errorArgs.errorMessage + "\n";
    errorMsg += "Error Code:    " + errorArgs.errorCode + "\n";
    
    // Determine the type of error and add specific error information.
    switch(errorArgs.errorType)
    {
        case "RuntimeError":
            // Display properties specific to RuntimeErrorEventArgs.
            if (errorArgs.lineNumber != 0)
            {
                errorMsg += "Line: " + errorArgs.lineNumber + "\n";
                errorMsg += "Position: " +  errorArgs.charPosition + "\n";
            }
            errorMsg += "MethodName: " + errorArgs.methodName + "\n";
            break;
        case "ParserError":
            // Display properties specific to ParserErrorEventArgs.
            errorMsg += "Xaml File:      " + errorArgs.xamlFile      + "\n";
            errorMsg += "Xml Element:    " + errorArgs.xmlElement    + "\n";
            errorMsg += "Xml Attribute:  " + errorArgs.xmlAttribute  + "\n";
            errorMsg += "Line:           " + errorArgs.lineNumber    + "\n";
            errorMsg += "Position:       " + errorArgs.charPosition  + "\n";
            break;
        default:
            break;
    }
    // Display the error message.
    alert(errorMsg);
}

Silverlight.js の OnError イベント ハンドラーの使用

Silverlight.js は、必要なオブジェクト タグ設定を行うことによって HTML で Silverlight プラグインをインスタンス化できるスクリプト関数のユーティリティ ライブラリです。 Silverlight.js を使ったインスタンス化手法には、OnError ハンドラー パラメーター用の既定のイベント ハンドラーも用意されています。 Silverlight.js の関数を使用する CreateObject 呼び出しで、onError パラメーターを指定しないか null に設定した場合、ネイティブ スクリプト エラーが発生すると、Silverlight.js に定義されている既定のハンドラー関数が呼び出されます。 Silverlight.js ファイルをインクルードし、その固有の関数を呼び出す方法の詳細については、「方法 : JavaScript を使用して Web ページに Silverlight を追加する」を参照してください。

重要 : 重要 :

Silverlight.js に定義されている既定の OnError イベント ハンドラー関数は、多くのエラーに対してダイアログ ボックスを表示します。 このような動作の本番コードまたは Web サイトを配置することは望ましくありません。 OnError を使用する場合は、Silverlight ベースのアプリケーションをリアルタイムに実際に配置する際に完全には除去できない多くの非同期エラーに対して呼び出します。

JavaScript における同期メソッド呼び出しと try/catch ブロック

同期メソッドの呼び出しでは、そのメソッドから制御が戻されるまで、呼び出し元の関数が待機状態になります。 JavaScript コードのブロックでエラーが発生したかどうかは、try/catch ステートメントを使ってテストできます。 try ブロックには、実行するコードを記述します。また、catch ブロックには、エラーが発生した場合に実行するコードを記述します。

同期メソッドの呼び出しに失敗しても、そのメソッドの呼び出しが try/catch ブロックに記述されていた場合、「ECMAScript 言語仕様」(ECMA-262) で記述されたエラー オブジェクトが、catch ブロックに渡され、onError イベントは生成されません。 onError イベントが生成されないので、onError イベント ハンドラーは呼び出されません。 同期メソッドの呼び出しに失敗した場合、そのメソッドの呼び出しが try/catch ブロック内に記述されていないときは、onError イベントが生成され、Silverlight プラグインの onError ハンドラーにルーティングされます。 onError ハンドラーにイベント引数として渡される ErrorType には、RuntimeError が設定されます。

エラー オブジェクトを介して catch ブロックに返される Silverlight 固有のエラー情報は、ErrorCode (Internet Explorer の場合のみ) および ErrorMessage だけです。 エラー オブジェクトの message プロパティには、エラー メッセージが設定されます。

現在、try/catch の機能は、Silverlight に対応したほとんどのブラウザーおよびオペレーティング システムでサポートされていますが、Apple Safari および Macintosh ではサポートされません。 この制限のため、すべての同期ランタイム メソッドには onError を使用することをお勧めします。

Silverlight の非同期エラー イベント (JavaScript)

非同期の呼び出しでは、呼び出しの直後に制御が戻ります。 非同期呼び出し中にエラーが発生した場合は、呼び出しの種類に応じたエラー イベントが生成されます。 ハンドラーが特定の非同期イベントにアタッチされていない場合、onError ハンドラーが呼び出されます。 代表的な非同期エラー イベントとしては、MediaFailed イベントがあります。

MediaFailed イベントにイベント ハンドラーをアタッチする方法を次の例に示します。

  <MediaElement x:Name="MediaPlayer" MediaFailed="MediaFailedHandler" />

MediaFailed イベントのイベント ハンドラーの例を次に示します。

function MediaFailedHandler(sender, args)
{

    // Create basic error message.
    var errorMsg = "\n Media Error Message     \n" ;

    // Add Media information.
    errorMsg += "MediaElement Name: " + sender.Name + "\n";
    errorMsg += "Media File Name: " + sender.Source + "\n";

    // Display error information.
    alert(errorMsg);  
}

Visual Studio における JavaScript デバッグの有効化

Silverlight ベースのアプリケーションを Visual Studio で作成することにより、JavaScript のコードを Visual Studio を使ってデバッグできます。 ブレークポイントを設定して、変数の値を表示したり変更したりできます。また、Immediate ウィンドウでスクリプトを実行することもできます。 Visual Studio で JavaScript をデバッグできるようにするには、Internet Explorer で [スクリプトのデバッグを使用しない] という設定をオフにする必要があります。 既定では、これらの設定のチェック ボックスはオンになっています。 [スクリプトのデバッグを使用しない] という設定をオフにすると、JavaScript コードにブレークポイントを設定できます。

メモ メモ :

Windows Vista または Windows 7 を実行している場合は、Visual Studio を管理者権限で実行する必要があります。管理者権限で実行しなかった場合、ブレークポイントは無視されます。

コミュニティの追加

追加
表示:
© 2015 Microsoft