2

今日、私はこのコードに出くわしました

internal  object UpdatePracownik(object employee)
{  
    lock (employee)
    {
        // rest of the code 
    }

    return employee;
}

これが機能へのアクセスをロックするための有効な解決策であるかどうか疑問に思っていましたか?

属性を使用する方が良いでしょうか

[MethodImpl(MethodImplOptions.Synchronized)] 

この種のロックの代わりに?

4

3 に答える 3

1

まあそれは依存します。すべてのスレッドが、同じグローバル可視オブジェクトをパラメータとして渡してこのメ​​ソッドを呼び出すと、すべて同じロックが表示され、問題は発生しません。

代わりに、各スレッドが独自のオブジェクトを渡してこのメ​​ソッドを呼び出す場合、すべてのスレッドが異なるロックを参照するため、ロックは役に立ちません。これが安全かどうかを確認するには、メソッドが呼び出されるコンテキストを知る必要があります。

あなたが提案した同期メソッドを使用すると、メソッド本体全体が次のlock(this)ようなステートメントでラップされます。

internal  object UpdatePracownik(object employee)
{
    lock (this)
    {
        // code        
    }
}

これにより、複数のスレッドによる実行の原子性が保証されますが、目的には粗すぎる可能性があり、一般的にはお勧めできません。

于 2012-01-18T12:55:03.700 に答える
1

属性を使用しMethodImplてメソッドを同期することは、メソッドに固有のオブジェクトをロックすることと同じです。

これは、一度に 1 つのスレッドのみがメソッドを実行できることを意味しますが、同じデータを使用しない限り、他のスレッドを除外する必要はないかもしれません。

これは、メソッド自体が同期されることも意味しますが、同じ識別子を使用して他のメソッドもロックしたい場合があります。たとえば、更新中に 1 つのオブジェクトを削除できないように、メソッドDeletePracownikを とともに同期する必要がある場合があります。UpdatePracownik

于 2012-01-18T12:58:53.603 に答える
0

'this' をロックするのと同じ理由で、従業員インスタンスをロックするのは悪い考えです。制御できないコードがこれらのインスタンスをロックし、デッドロックを引き起こす可能性があります ( blogs.msdn.com/b/bclteam/archive/ 2004/01/20/60719.aspx )。private メンバーを使用することをお勧めします。

private readonly object _lock = new object();

...

lock (_lock)
{
 ..
}

さらに、ReaderWriterLockSlimに慣れておく必要があります。書き込み操作が進行中でない限り、特定の関数への同時アクセスを許可したい場合がよくあります。

private readonly ReaderWriterLockSlim _rwLock = new ReaderWriterLockSlim();

public void ReadOp()
{
     _rwLock.EnterReadLock();  //only blocks if write lock held
     try
     {
         //do read op
     }
     finally
     {
         _rwLock.ExitReadLock();
     }
}

public void WriteOp()
{
     _rwLock.EnterWriteLock();  //blocks until no read or write locks held
     try
     {
         //do write op
     }
     finally
     {
         _rwLock.ExitWriteLock();
     }
}
于 2012-01-18T13:28:55.857 に答える