现有的与Parallel.For类似的LINQ扩展方法?
现有的与Parallel.For类似的LINQ扩展方法?
可能重复:
LINQ中对于IEnumerable
linq对于IEnumerable的扩展方法非常方便... 但如果你只是想对枚举中的每个项目应用一些计算而不返回任何东西,它就不那么有用了。所以我想知道也许我只是错过了正确的方法,或者它真的不存在,我宁愿使用内置的版本,如果有的话... 但我还没有找到一个:-)
我刚才确信某个地方有一个.ForEach方法,但我还没有找到它。与此同时,我为了其他人的方便编写了自己的版本:
using System.Collections; using System.Collections.Generic; public delegate void Function(T item); public delegate void Function(object item); public static class EnumerableExtensions { public static void For(this IEnumerable enumerable, Function func) { foreach (object item in enumerable) { func(item); } } public static void For (this IEnumerable enumerable, Function func) { foreach (T item in enumerable) { func(item); } } }
用法是:
myEnumerable.For
现有的LINQ扩展方法与Parallel.For类似吗?
在这个问题中,提到了在List
解决方法是使用List
Listnumbers = new List { 1, 2, 3, 4, 5 }; numbers.ForEach(num => Console.WriteLine(num));
这段代码会将numbers集合中的每个元素都输出到控制台。
另外,还某些情况下可能需要自己编写一个类似的方法来解决问题。这种方法可能会基于Parallel.For来实现并行处理。代码示例如下:
public static void ParallelForEach(this IEnumerable collection, Action action) { Parallel.ForEach(collection, action); }
这段代码定义了一个扩展方法ParallelForEach,可以在IEnumerable
要解决这个问题,可以使用List
在Microsoft Research的反应式扩展框架中,确实添加了类似的功能。
在System.Interactive程序集中,他们包含了Run()和Do()两个扩展方法,用于IEnumerable
Do(action)方法会对每个元素执行操作并将其返回。这对于在linq查询中添加日志非常有用,例如:
var res = GetRandomNumbers(100).Take(10)
.Do(x => Console.WriteLine("Source -> {0}", x))
.Where(x => x % 2 == 0)
.Do(x => Console.WriteLine("Where -> {0}", x))
.OrderBy(x => x)
.Do(x => Console.WriteLine("OrderBy -> {0}", x))
.Select(x => x + 1)
.Do(x => Console.WriteLine("Select -> {0}", x));
这将导致以下结果:
Source -> 96
Where -> 96
Source -> 25
Source -> 8
Where -> 8
Source -> 79
Source -> 25
Source -> 3
Source -> 36
Where -> 36
Source -> 51
Source -> 53
Source -> 81
OrderBy -> 8
Select -> 9
9
OrderBy -> 36
Select -> 37
37
OrderBy -> 96
Select -> 97
97
Run(action)方法类似于foreach循环,意味着它在执行操作时会折叠序列。
你可以在这里阅读更多相关信息:http://community.bartdesmet.net/blogs/bart/archive/2009/12/26/more-linq-with-system-interactive-the-ultimate-imperative.aspx
Rx框架可以在这里找到:http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx
我认为这个功能被低估了。
存在这个问题的原因是LINQ是函数式的,它用于查询数据并返回结果。LINQ查询不应该改变应用程序的状态(除了一些像缓存的例外情况)。由于foreach不返回任何结果,它没有很多不涉及改变传入对象状态的用途。而如果你需要一个Foreach()扩展方法,自己实现一个是很容易的。
然而,如果你想要对输入进行操作,并对每个项目调用一个返回结果的函数,LINQ通过其select方法提供了一种方法。
例如,下面的代码对列表中的每个项目调用一个函数委托,如果该项目为正数,则返回true:
static void Main(string[] args) { IEnumerablelist = new List () { -5, 3, -2, 1, 2, -7 }; IEnumerable isPositiveList = list.Select (i => i > 0); foreach (bool isPositive in isPositiveList) { Console.WriteLine(isPositive); } Console.ReadKey(); }
解决方法是使用LINQ的select方法来替代foreach循环。通过使用select方法,我们可以对每个项目应用一个函数,并返回结果。这样我们就可以避免直接使用foreach循环,从而保持LINQ的函数式特性。
更多信息请参见stackoverflow.com/questions/858978和blogs.msdn.com/b/ericlippert/archive/2009/05/18。