2011-07-03 9 views
5

私はランダムに "KeyNotFoundException"を投げているC#Silverlightアプリケーションを持っています。どのような鍵が見つからないのか分かりません。これは私に2つの質問につながります:KeyNotFoundException info

  1. KeyNotFoundExceptionは、見つけようとしたキーを保存/公開していますか?私がdocumentationを見ると、この情報が利用可能であることを暗示した何も見ませんでした。
  2. 一般的なApplication.UnhandledExceptionイベントハンドラでこの例外をキャッチ/ロギングしています。私の質問は、私がここでイベントをキャッチする場合、ExceptionObjectをKeyNotFoundExceptionに変換し、#1で尋ねられたように公開されている場合でもキー情報を取得できますか?

ありがとうございました!

+1

スタックトレースを記録して、エラーの原因がわかるようにしてください。 –

答えて

4

KeyNotFoundExceptionは、キーが存在しない場合に、指定されたキーを持つディクショナリから値を取得しようとしているために発生します。例:

var dictionary = new Dictionary<string, string>(); 
var val = dictionary["mykey"]; 

辞書が使用されているすべての場所を見て自分自身を判断できます。そのための一般的なベストプラクティスは、存在しない可能性のある辞書の値を探す場合は、TryGetValueを使用することです。すべての時間は、より高価な操作であり、不要な例外をキャッチ:

string val; 
if(dictionary.TryGetValue("mykey", out val)) 
{ 
    //The key was found. The value is in val. 
} 
else 
{ 
    //The key was not present. 
} 

あなたは問題が起こっている場所を正確に決定するために、彼らKeyNotFoundExceptionStackTraceプロパティを見ることができます。すべての例外にはStackTraceというプロパティがあります。そのため、グローバルエラーハンドラにあった例外の種類を気にする必要はありません。

private void Application_UnhandledException(object sender, 
     ApplicationUnhandledExceptionEventArgs e) 
    { 
     var stackTrace = e.ExceptionObject.StackTrace; 
     //Log the stackTrace somewhere. 
    } 

それとも、あなたはそれが例外の種類を伝えることができるようにしたい場合:たとえば

private void Application_UnhandledException(object sender, 
     ApplicationUnhandledExceptionEventArgs e) 
    { 
     if (e.ExceptionObject is KeyNotFoundException) 
     { 
      //This was a KeyNotFoundException 
     } 
    } 
3

私はこの問題を見つける最良の方法は、Application.UnhandledExceptionメソッドで特定の例外のStackTraceを記録することだと思います。 StackTraceでは、問題の原因(例外の原因となっているメソッドの名前、ファイルの名前と行)を見つけることができます。このようにして、コードに何が間違っているのかを理解できます。 できるだけ多くのログを記録してください。

4

は辞書がKeyNotFoundExceptionスローすると、それはあなたを伝えるを試みませんどのキーそれは見つけようとした。そのため、私は通常、自分の辞書に拡張メソッドを使用しようとします。そのため、プログラムが途切れた場合、どのキーを検索しようとしたのか分かります。スタックトレースが有用であることは分かっていますが、特にルックアップがループ内で実行されている場合は、十分ではありません。

public static TValue GetOrThrow<TKey,TValue>(this IDictionary<TKey,TValue> d, TKey key) 
{ 
    try 
    { 
     return d[key]; 
    } 
    catch(KeyNotFoundException ex) 
    { 
     throw new KeyNotFoundException(key.ToString() 
      + " was not found in the dictionary"); 
    } 
} 

更新/明確化

それはToString()を上書きしないタイプであるかもしれないので、私は実際にkey.ToString()を呼び出すことはありません。デフォルトでは、タイプ名:"MyLibrary.SomeType was not found."が出力されますが、これは"{ managerId: 123, employeeId: 456} was not found."とは異なります。また、例外メッセージに特定のキー値を置くことは、それはハードで例外を集約することができますことを、私を見つけた

var serializedKey = Newtonsoft.Json.JsonConvert.SerializeObject(
    key, 
    new JsonSerializerSettings 
    { 
     //make it easy for humans to read 
     Formatting = Formatting.Indented, 
     //don't break on loops...that would cause a new error that hides the KeyNotFound! 
     ReferenceLoopHandling = ReferenceLoopHandling.Ignore 
    }); 

はので、代わりに、私はそうのように、JSONへのシリアライズログは、使用するツールの種類によって異なります。 (私は外部例外のメッセージによってエラーをグループ化するものと一緒に働いています)。これがあなたに影響を及ぼした場合は、内部例外で詳細を置きたいと思うかもしれません:
throw new KeyNotFoundException( "key was not found", new KeyNotFoundException(serializedKey));

+0

最も魅力的な答え。 – Aeron

0

のWindows Phone用のSilverlightがwsHttpBindingをサポートしていないので、それはあるので、あなたは、あなたがbasicHttpBindingへのサービスと、それは

に動作します変更します