2017-11-09 12 views
0

最近、何人かのユーザーが報告しましたが、私はキャッチできませんでした。 bound error detailsインデックスが配列の境界外にありました。C#(Catch and Con(c)(q)ure)

リサーチによると、辞書をConcurrentDictionaryに変更することで解決できると思います。質問はどうすればエラーをキャッチできますか?追加(TryAddまたはAddorUpdate)のためにConcurrentDictionaryを使用する最良の方法は何ですか?

編集:参考文献のコード。ここで、(これを行うのより良い方法が確かにあります)このようにセッションIDを使用するための理由を気に決して

private static Dictionary<string, SportsFacility> _selectedFacilities = new Dictionary<string, SportsFacility>(); 
    public static SportsFacility SelectedFacility 
    { 
     get 
     { 
      return _selectedFacilities.ContainsKey(HttpContext.Current.Session.SessionID) ? _selectedFacilities[HttpContext.Current.Session.SessionID] : null; 
     } 
     set 
     { 
      if (_selectedFacilities.ContainsKey(HttpContext.Current.Session.SessionID)) 
      { 
       _selectedFacilities[HttpContext.Current.Session.SessionID] = value; 
      } 
      else 
      { 
       _selectedFacilities.Add(HttpContext.Current.Session.SessionID, value); 
      } 
     } 
    } 
+0

エラーが発生したコードを表示できますか? –

+0

この[MCVE]を読んで、あなたの質問に応じてフォーマットしてください。 –

+0

ここをクリックしてください。ヒントありがとうございます。 –

答えて

1

はあなたのコードに若干の改善である:静的なインデックスを使用して

private static readonly object _selectedFacilitiesLocker=new object(); 
private static Dictionary<string, SportsFacility> _selectedFacilities = new Dictionary<string, SportsFacility>(); 

private static bool TryGetSelectedFacility(string key, out SportsFacility facility) 
{ 
    // Since you are in a web environment and are using statics, you must lock this index whenever you use it 
    lock(_selectedFacilitiesLocker) 
    { 
     return _selectedFacilities.TryGetValue(key, out facility); 
    } 
} 
private static void UpdateSelectedFacility(string key, SportsFacility facility) 
{ 
    // Since you are in a web environment and are using statics, you must lock this index whenever you use it 
    lock(_selectedFacilitiesLocker) 
    { 
     _selectedFacilities[key] = facility; 
    } 
} 
public static SportsFacility SelectedFacility 
{ 
    get 
    { 
     SportsFacility facility; 
     if(!TryGetSelectedFacility(HttpContext.Current.Session.SessionID, out facility)) 
      return null; 
     else 
      return facility; 
    } 
    set 
    { 
     UpdateSelectedFacility(HttpContext.Current.Session.SessionID, value); 
    } 
} 

( "_selectedFacilities")は、Webサーバーのようなマルチスレッド環境でのコードの問題を綴っています。このようなデザインが必要な場合(なぜそうすべきではないのか理由はありません)、使用するたびにその周りにロックを追加する必要があります。さもなければ、あなたが生産中であるとすぐに、あらゆる種類の奇妙なバグを得るでしょう。あなたが喜んで自分自身をテストしている間はうまくいくように見えますが、残念ながら人生はそれほど簡単ではありません。

+0

親切なアドバイスと改善がありがとう –

1

この例外は、同期なしで複数のスレッドの辞書オブジェクトを使用することによって発生しました。あなたがロックを使用せずにConcurrentDictionaryを使用することができ、言ったようにあなたは、(@KEkegrenが示唆したように)ロックで辞書オブジェクトへのアクセスをsyncronizingによって、または手動でsyncronizingに加えてReaderWriterLockSlim

でそれを解決することができます。これは.NET Framework 4以上でサポートされています。

ConcurrentDictionaryのすべての操作はアトミックです。つまり、すべてのメソッドがスレッドセーフであり、アクセスを同期化する必要はありません。

ただし、辞書と同じ方法で使用しないでください。つまり、キーの存在を確認してから新しい価値を追加するべきではありません。代わりに、AddOrUpdateを使用すると、単一のアトミック操作で何をしようとしているのかがわかるので、ケースでAddOrUpdateを使用する必要があります。

0

特定のアプローチを批判するのではなく、より良い解決策を示す答えを提供してください。

これは、セッション変数を使用して静的辞書で行うことと同じことです。

public static SportsFacility SelectedFacility 
{ 
    get 
    { 
     return (Session["SelectedFacility"] as SportsFacility); 
    } 
    set 
    { 
     Session["SelectedFacility"] = value; 
    } 
} 

幸運!

+1

共有辞書を使用してすべてのセッションデータにアクセスして列挙できます。このディクショナリの目的が何であるかは疑問ではなく、OPはセッション状態を使用するためのコメントに答えなかった。 – fofik

+0

あなたは確かに正しいです。彼はまたコレクションを列挙しているかもしれません。私たちは彼が私たちに与えたコードだけで動作することができます。 –

関連する問題