2016-07-12 8 views
0

すべてのリソースへの基本パスを持つファイルがあります。たとえば:もちろんコードで競合状態が発生しますか?

build/scripts/script1.js 
build/scripts/script2.js 

私は、例えば、ベースパスを必要とする:

https://example.org/SuperDuperSite/build/scripts/script1.js 

私が何を期待していたどのようなパスで、起動時にグローバル辞書にファイルをロードしました。辞書は一度だけ読み込まれる必要があります。残念ながら、私が知る限り、基本パスは最初のリクエストまで利用できません。だからasp.net私はapplication_startではなくapplication_beginrequestを使用する必要があります。これについて悪い点は、マルチスレッドの問題に取り組まなければならないことです。私は本当に一度にそれをロードする必要がある場合には、すべて単一の要求のために呼び出されます

lock(_lock) { 
    if (_dictionary == null) { 
     LoadDictionary(); 
    } 
    } 

:次のコードの種類を書くために私を強制的に

。私は本当にこれが好きではありません。私は、パフォーマンス上の理由からすべてのリクエストをロックする必要はありません。一つの解決策は、私たちが思いついたの大学に話をした後、この溶液を用いだから、

if (_dictionary == null) 
{ 
    lock(_lock) { 
     if (_dictionary == null) { 
     LoadDictionary(); 
     } 
    } 
} 

私はすべて単一の要求をロックオンするために必要とされないだろうが、複数のスレッドが起動時に、このセクションを取得してしまった場合、私はそれから保護しますそのオブジェクトがロック内で再びヌルであるかどうかをチェックします。このコードは動作するのでしょうか、競合状態に陥るでしょうか?

+0

基本URLを含めるのが非常に複雑です。あなたがスタートアップ時に辞書にロードする道を行く理由はありますか? –

+1

これを正しい角度から攻撃してもよろしいですか?相対パス要求を行うことができない理由はありますか? –

+1

C#ではダブルチェックロックが安全です。コードサンプルの条件は逆ですが、他の細かいものです。 –

答えて

1

二重チェックロックを使用する場合は注意してください。

はい、それはスレッドセーフですが、あなたの特定のコードにあなたは_dictionaryは、他のスレッド(nullチェックを渡す)ことでをインスタンス化されているが、完全にはまだを取り込まない微妙なバグに遭遇するかもしれません部分的に人口が多い辞書にアクセスしようとする可能性があります。そして、これら二つのうちの一つで終わる:

  1. をあなたは(もそのパフォーマンスへの影響が付属しています)ConcurrentDictionaryを使用している場合を除き、あなたがかもしれ辞書を読み込むときに、結果を欠落している、または
  2. 悪化しています辞書に同時に読み書きしたり、デッドロックを引き起こしたりすることがあります(たとえば、Dictionaryクラスは多くのコードでデッドロックを引き起こすことが知られています)。

(ダブルチェック)bool _dictionaryLoadedフラグは、おそらく優れている、LoadDictionary()の終わりにtrueに裏返します。

.NET 4を使用している場合は、Lazy<>を使用してください。それはもっときれいです。LoadDictionaryをinit関数として使用するだけです。

編集:Lazy <>はinternally implemented with a double-checked lockです。

関連する問題