これは C# の詳細な質問です。
オブジェクトを持つクラスがあり、そのオブジェクトがロックによって保護されているとします。
Object mLock = new Object();
MyObject property;
public MyObject MyProperty {
get {
return property;
}
set {
property = value;
}
}
ポーリング スレッドでそのプロパティをクエリできるようにしたい。また、スレッドがそのオブジェクトのプロパティをときどき更新することも必要です。また、ユーザーがそのプロパティを更新できる場合もあり、ユーザーはそのプロパティを表示できるようにしたいと考えています。
次のコードはデータを適切にロックしますか?
Object mLock = new Object();
MyObject property;
public MyObject MyProperty {
get {
lock (mLock){
return property;
}
}
set {
lock (mLock){
property = value;
}
}
}
「適切に」とは、つまり、電話したい場合
MyProperty.Field1 = 2;
または何でも、更新を行っている間、フィールドはロックされますか? 'get' 関数のスコープ内で equals 演算子によって行われる設定ですか、それとも 'get' 関数 (したがってロック) が最初に終了し、次に設定が終了し、次に 'set' が呼び出されてバイパスされますか?ロック?
編集:これは明らかにうまくいかないので、どうしますか?次のようなことをする必要がありますか?
Object mLock = new Object();
MyObject property;
public MyObject MyProperty {
get {
MyObject tmp = null;
lock (mLock){
tmp = property.Clone();
}
return tmp;
}
set {
lock (mLock){
property = value;
}
}
}
多かれ少なかれ、コピーにしかアクセスできないことを確認するだけです。つまり、2 つのスレッドが同時に「get」を呼び出すと、それぞれが同じ Field1 の値で開始されます (右?)。意味のあるプロパティで読み取りと書き込みのロックを行う方法はありますか? それとも、データ自体ではなく関数のセクションをロックするように自分自身を制限する必要がありますか?
この例が理にかなっているように、MyObject はステータスを非同期的に返すデバイス ドライバーです。シリアル ポート経由でコマンドを送信すると、デバイスは独自の時間内にそれらのコマンドに応答します。現在、ステータスをポーリングするスレッド (「まだそこにいますか? コマンドを受け入れることができますか?」) と、シリアル ポートで応答を待機するスレッド (「ステータス文字列 2 を取得しました。すべて問題ありません」) があります。 )、次に、他のコマンド (「ユーザーがこのことを実行してほしい」) を受け取り、ドライバーからの応答を送信する UI スレッド (「私はちょうどそれを実行しました。それで UI を更新します」)。オブジェクトのフィールドではなく、オブジェクト自体をロックしたいのはそのためです。このクラスのすべてのデバイスが同じ動作をするわけではありません。