web-dev-qa-db-ja.com

C#:静的メソッドが複数のスレッドから呼び出されるとどうなりますか?

私のアプリケーションには、複数のスレッドから同時に呼び出される静的メソッドがあります。データが混同される危険はありますか?

最初の試みでは、メソッドは静的ではなく、クラスの複数のインスタンスを作成していました。その場合、私のデータは何らかの形で混同されました。時々しか起こらないので、これがどのように起こるかはわかりません。まだデバッグ中です。しかし、今ではメソッドは静的です。今のところ問題はありません。たぶんそれは運だ。確かにわかりません。

87
TalkingCode

メソッド内で宣言された変数(「captured」変数の例外を除く)は分離されているため、固有の問題は発生しません。ただし、静的メソッドが共有状態にアクセスする場合、すべてのベットはオフになります。

共有状態の例は次のとおりです。

  • 静的フィールド
  • 共通キャッシュからアクセスされるオブジェクト(非シリアル化)
  • 複数のスレッドが同じオブジェクトに触れている可能性がある場合、入力パラメーター(およびそれらのオブジェクトの状態)を介して取得されたデータ

共有状態がある場合は、次のいずれかを行う必要があります。

  • 一度共有できる状態を変更しないように注意してください(より良い:状態を表すために不変オブジェクトを使用し、ローカル変数に状態のスナップショットを取ります-whatever.SomeDataを繰り返し参照するのではなく、whatever.SomeDataonceをローカル変数に入れてから、その変数を使用するだけです-これは不変の状態にのみ役立つことに注意してください!)
  • データへのアクセスを同期します(すべてのスレッドが同期する必要があります)-相互に排他的または(より詳細な)リーダー/ライター
88
Marc Gravell

はい、それは単なる運です。 ;)

メソッドが静的であるかどうかは関係ありません。データが静的であるかどうかは重要です。

各スレッドが独自のデータセットを持つクラスの独自の個別のインスタンスを持っている場合、データが混同されるリスクはありません。データが静的である場合、データのセットは1つだけであり、すべてのスレッドが同じデータを共有するため、データを混同しない方法はありません。

別々のインスタンスのデータがまだ混同されている場合は、データが実際には分離されていない可能性が高くなります。

23
Guffa

静的メソッドは、複数のスレッドに適しています。

一方、静的データは、一度に1つのスレッドのみがデータの読み取りまたは書き込みを行うように、異なるスレッドから同じデータにアクセスする試みを制御する必要があるため、問題を引き起こす可能性があります。

13
Doug Ferguson

MSDNは常に言う:

この型のpublic static(Visual BasicではShared)メンバーは、スレッドセーフです。インスタンスメンバーは、スレッドセーフであるとは限りません。

編集:ここにいる人たちが言うように、常にそうとは限らず、明らかにこれはBCLで​​このように設計されたクラスに適用され、これが適用されないユーザー作成のクラスには適用されません。

7
Marcote