web-dev-qa-db-ja.com

List <T>は読み取りに対してスレッドセーフですか?

次の擬似コードはスレッドセーフですか?

IList<T> dataList = SomeNhibernateRepository.GetData();

Parallel.For(..i..)
{
    foreach(var item in dataList)
    {
       DoSomething(item);
    }
}

リストは変更されることはなく、繰り返されて並行して読み取られるだけです。フィールドやそのようなものへの書き込みは一切ありません。

ありがとう。

33
user315648

はい、_List<T>_は、何も書き込まない限り、複数のスレッドから同時に読み取ることができます。

から ドキュメント

_List<T>_は、コレクションが変更されていない限り、複数のリーダーを同時にサポートできます。

編集:あなたのコードは必ずしも_List<T>_を使用しないことに注意してください-ただ_IList<T>_。 GetData()によって返される型を知っていますか? GetData()を制御している場合、実際に_List<T>_を返しているのであれば、返されるリストがスレッドセーフであるということを文書化することをお勧めします。

49
Jon Skeet

DoSomething(item)dataListを変更しない限り、完全にスレッドセーフです。そうではないと言ったので、そうです、それはスレッドセーフです。

3
jakobbotsch

誰もリストを変更しないようにするには、IEnumerableを介してリストにアクセスできます

IEnumerable<T> dataList = SomeNhibernateRepository.GetData();

Parallel.For(..i..)
{
    foreach(var item in dataList)
    {
       DoSomething(item);
    }
}
1

あなたが言う理由が正しいなら、私はそう言うでしょう。しかし、あなたが言ったり考えたりすることは、実際には何が起こるかではないかもしれません。あなたが言ったことをコードでどのように言うことができますか?リストが変更されないという制約を適用するにはどうすればよいですか?

0
Brett Walker