私はInterlocked.CompareExchangeを使用する方が高速であることを知っていますが、ロックに制限されている場合は最良の方法を探しています。ロックを使用して、以前の値に基づいて2つの関連フィールドを変更する最も効率的な方法はありますか?
Joe Albahari says the following:
それは安全に(例えば、それが「増加」にPERCENTCOMPLETE値が可能です)、その前回値に基づいて新しいProgressStatusオブジェクトを割り当てることも可能です - コードの複数行にわたってロックせず。
編集:@ drchの回答に基づいて更新されたコード。小さなより効率的なロックでこれを行う方法があるのを待っています。このロックは、読み込み、書き込み、および新しいコンストラクタをすべてロック内に持ちます。より小さな\より効率的なロックを望んでいた。ありがとう。
class ProgressStatus
{
public readonly int PercentComplete;
public readonly string StatusMessage;
public ProgressStatus(int percentComplete, string statusMessage)
{
PercentComplete = percentComplete;
StatusMessage = statusMessage;
}
}
class Test
{
readonly object _statusLocker = new object();
ProgressStatus _status;
void IncreaseProgress()
{
lock (_statusLocker)
_status = new ProgressStatus(_status.PercentComplete + 10, _status.StatusMessage);
}
}
IncreaseProgressのみ、正しいつのスレッドによって実行されますか? 2つのスレッドが同じstatusCopyをキャッシュすると、複数のスレッドがそれを実行していると、更新が失われる可能性があるからです。 – aKzenT
@ aKzenTいいえこれは、多くのスレッドがIncreaseProgressを一度に呼び出すと仮定しています。コードの欠陥を指摘してくれてありがとう、これは私がジョーAlbahariが話している1つのライナーを探している理由です。 –
http://msdn.microsoft.com/en-us/library/dd78zt0c.aspxを見ましたか? –