IEnumerable<> を返すことはスレッドセーフですか? 質問する

IEnumerable<> を返すことはスレッドセーフですか? 質問する

Visual Studio 2008 C# .NET 3.5 プロジェクトがあり、そこでスレッドセーフなFooオブジェクト プールを作成したいと考えています。

public class FooPool
{
    private object pool_lock_ = new object();
    private Dictionary<int, Foo> foo_pool_ = new Dictionary<int, Foo>();

    // ...

    public void Add(Foo f)
    {
        lock (pool_lock_)
        {
            foo_pool_.Add(SomeFooDescriminator, f);
        }
    }

    public Foo this[string key]
    {
        get { return foo_pool_[key]; }
        set { lock (pool_lock_) { foo_pool_[key] = value; } }
    }

    public IEnumerable<Foo> Foos
    {
        get
        {
            lock (pool_lock_)
            {
                // is this thread-safe?
                return foo_pool_.Select(x => x.Value);
            }
        }
    }
}

public IEnumerable<Foo> Foos { get; }この関数はスレッドセーフですか? それとも、結果を複製して新しいリストを返す必要がありますか?

ベストアンサー1

いいえ、違います。

呼び出し元が辞書を列挙している間に別のスレッドが辞書に追加すると、エラーが発生します。

代わりに、次の操作を実行できます。

lock (pool_lock_) {
    return foo_pool.Values.ToList();
}

おすすめ記事