2012-04-17 31 views
2

ReSharper重构了一个foreach循环我不得不这样做。我想通过委托的BeginInvoke的产卵一堆线程使用不同的参数,存储在一个列表,以及存储IAsyncResults一个集合中:通过LINQ Select调用错误代码产生新线程?

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

我的本能反应是,这是不是一个好的做法。 BeginInvoke会导致产生新线程的副作用,并且传递给Select的函数不应导致副作用。

或者它可以,因为我没有改变调用线程中的任何东西?

+6

在你问自己“这是一个好习惯吗?”之前问自己“这个代码是否实现了我所描述的行为?”它不是;这段代码只是创建一个查询对象。您创建了一个对象,意思是“我是从该列表中产生一系列异步结果的查询”。 *正在*该查询不会导致查询*执行*。如果你想执行查询并将结果存储在一个集合中,你将不得不编写更多的代码。 – 2012-04-17 00:53:34

+0

它本身并没有做任何事情,但在某些情况下它可能是合适的。然而,当你调用BeginInvoke时,我猜你通常希望线程在那里和那里开始,所以在这种情况下,LINQ查询与foreach循环完全不同。 – Jimmeh 2012-04-17 17:13:56

回答

2

我觉得很难说这是否是一种好的做法,这取决于你如何使用它。

但是,像这样使用LINQ时要记住的重要一点是Select()(以及其他许多LINQ方法)实际上并没有迭代集合并执行代码。只有在迭代所得到的集合时才会发生这种情况,通常使用foreachToArray()

+0

是的,我认为这可能是适当的,只有当你不介意没有完全控制线程产生的时候。我忘记了LINQ的懒惰。 – Jimmeh 2012-04-17 17:09:07

3

这应该没问题。创建一个新线程并不是真正的副作用。你没有修改任何值。 BeginInvoke被调用,您正在存储结果IAsyncResult

但是,你必须记住,没有什么会阻止。你必须自己管理所有事情的同步。