2

スレッド セーフのために ReaderWriterLockSlim を利用する多くのプロパティを実装しようとしています。したがって、ほとんどの場合と同様に、すべてのプロパティで次のような結果になります。

public string Name
{
    get
    {
        rwLock.EnterReadLock();
        try {
            return name;
        }
        finally {
            rwLock.ExitReadLock();
        }
    }
    set
    {
        rwLock.EnterWriteLock();
        try {
            name = value;                    
        }
        finally {
            rwLock.ExitWriteLock();
        }
    }
}

これは 10 個のプロパティで非常に冗長で反復的な感じがするので、より DRY な実装を探しています。

明らかな解決策は、破棄時にロックを解放し、スレッド セーフな操作を using ステートメント内に配置できるようにするクラスにラップすることです。これと他のいくつかの情報源によると、明らかにこれはあまり安全ではありません。

そこで、ラムダ式と匿名メソッドを使用して見栄えの良いソリューションを考え出そうとしました。

private TResult ThreadSafeRead<TResult>(Func<TResult> value)
{
    rwLock.EnterReadLock();
    try {
        return value();
    }
    finally {
        rwLock.ExitReadLock();
    }            
}

private void ThreadSafeWrite(Action value)
{
    rwLock.EnterWriteLock();
    try {
        value();
    }
    finally {
        rwLock.ExitWriteLock();
    }
}

public string Name
{
    get { return ThreadSafeRead(() => name); }
    set { ThreadSafeWrite(() => { name = value; }); }
}       

これにより、私を悩ませていた繰り返しコードがなくなりましたが、元の詳細な実装と同じくらいスレッドセーフかどうかはわかりません。

これが生成する MSIL とマルチスレッド理論をよりよく理解している人は、私の実装が安全かどうかを教えてくれますか?

4

2 に答える 2

1

人々がこれに取り組むのを私が見た通常の方法は、ロックをオブジェクトにラップし、次の行に沿って何かを行うことです。

using (var obj = new ReadOnlyLock(this.rwLock))
{
    this.name = value;
}

私はこれをしないことを認めます (ロックを取得するためだけに別のオブジェクトを作成するのはなぜですか?) が、一部の人が最も重要と見なすより良いスタイルの目標を達成します...

于 2012-06-29T17:08:05.227 に答える
-1

はい、あなたのブログ投稿で言及されている問題は存在します。この主題のより完全な扱いについては、Joe Duffy の投稿を参照してください。

あなたのコードは非同期例外に苦しんでいますか? おそらく、ASP.NET で実行しているときにのみ発生し、現在の要求がタイムアウトにより中止されます。もちろん、さまざまな理由で自分でスレッドをアボートするべきではありません。

この問題に実質的に関心を持つべきではないと思います。

于 2012-06-29T17:19:31.167 に答える