2012-04-17 5 views
2

ReSharperは私がこれに似ていたforeachループをリファクタリングしました。私は、リストに保存されている異なるパラメータ、とデリゲートのBeginInvokeを介して、スレッドの束を起動し、コレクション内のIAsyncResultsを保存したい:LINQ経由で新しいスレッドを生成していますか?コールの不良コードを選択していますか?

var asyncResults = mylist.Select(x => myDelegate.BeginInvoke(x, null, null)); 

私の本能的な反応は、これは良い習慣ではないということです。 BeginInvokeは新しいスレッドが生成される副作用を引き起こし、Selectに渡された関数は副作用を引き起こすべきではありません。

私は呼び出しスレッドで何も変更していないので、多分それは大丈夫ですか?

+6

「これは良い方法ですか? 「このコードは、私が記述している振る舞いを実装するのか?それはしません。このコードはクエリオブジェクトを作成するだけです。 「このリストから一連の非同期結果を生成するクエリです」という意味のオブジェクトを作成しました。 *そのクエリであると*クエリを*実行する*ことはありません。クエリを実行して結果をコレクションに格納する場合は、より多くのコードを記述する必要があります。 –

+0

これは単独では何もしませんが、状況によっては適切かもしれません。しかし、BeginInvokeを呼び出すと、一般的にはスレッドが開始されることが望ましいと思うので、LINQクエリはこの場合foreachループとはまったく異なります。 – Jimmeh

答えて

2

これは良い練習かどうかを判断するのは難しいと思いますが、それはどうやって使用しているかによって異なります。

LINQをこのように使用するときに覚えておくべき重要なことは、Select()(および他の多くのLINQメソッド)が実際にコレクションを繰り返し処理してコードを実行しないことです。これは、結果のコレクションを反復するときにのみ発生します。通常はforeachまたはToArray()を使用します。

+0

ええ、これは、スレッドが正確に生成されたときを完全に制御できないことが気にならない場合にのみ、これが適切であると思います。私はLINQの怠惰を忘れていました。 – Jimmeh

3

これは問題ありません。新しいスレッドを作成することは、実際には副作用ではありません。あなたは値を変更していません。 BeginInvokeが呼び出され、結果としてIAsyncResultが保存されます。

あなたは、何もブロックされないことを覚えておく必要があります。自分ですべての同期を管理する必要があります。

関連する問題