越来越怪异的结果,而使用任务并行库? [英] Getting weird result while using Task Parallel Library?
问题描述
我试图做使用TPL一些过滤器的任务。在这里,我简化了code根据条件筛选号码。这里是code。
I am trying to do some filter task using TPL. Here I am simplifying the code to filter number based on condition. Here is the code.
public static void Main (string[] args)
{
IEnumerable<int> allData = getIntData ();
Console.WriteLine ("Complete Data display");
foreach (var item in allData) {
Console.Write(item);
Console.Write(" | ");
}
Console.WriteLine ();
filterAllDatas (ref allData, getConditions ());
foreach (var item in allData) {
Console.Write(item);
Console.Write(" | ");
}
Console.WriteLine ();
}
static void filterAllDatas(ref IEnumerable<int> data, IEnumerable<Func<int,bool>> conditions)
{
List<int> filteredData = data.ToList ();
List<Task> tasks = new List<Task>();
foreach (var item in data.AsParallel()) {
foreach (var condition in conditions.AsParallel()) {
tasks.Add(Task.Factory.StartNew(() => {
if (condition(item)) {
filteredData.Remove(item);
}
}));
}
}
Task.WaitAll(tasks.ToArray());
data = filteredData.AsEnumerable ();
}
static IEnumerable<Func<int,bool>> getConditions()
{
yield return (a) => { Console.WriteLine("modulo by 2"); return a % 2 == 0;};
yield return (a) => { Console.WriteLine("modulo by 3"); Thread.Sleep(3000); return a % 3 == 0;};
}
static IEnumerable<int> getIntData ()
{
for (int i = 0; i < 10; i++) {
yield return i;
}
}
下面,它是简单code键滤除整数其由两个或三个分割。现在,如果我删除线程睡眠code的工作完美,但如果我把它不是。
Here, it is simple code to filter out integer which is divided by two or three. Now, if I remove that thread sleep code work perfectly but if I put that it is not.
通常是指未经Thread.sleep代码,这两个条件执行10次如对于每一个数字。但是,如果我添加了Thread.Sleep第一个条件执行7次,并执行第二十三次。而且因为这极少数的跳过状态。我试着调试,但没有得到任何可以指出问题,我的code。
Normally means without Thread.Sleep , both condition execute 10 times e.g. for every number. But if I add Thread.Sleep first condition executes 7 times and second executes thirteen times. And because of this few number skip the condition. I try to debug but didn't get anything that can point out issue with my code.
有没有达到这个什么好的办法?像过滤条件上的数据可以工作异步和并行以提高性能?
Is there any good way to achieve this? Like filter condition on data can work async and parallel to improve performance ?
code是仅用于演示的目的。
Code is for demo purpose only.
FYI:目前我使用单声道与Windows机器Xamarine工作室。
FYI: Currently I am using Mono with Xamarine studio on windows machine.
请让我知道如果任何进一步的细节需要。
Please let me know if any further details needed.
推荐答案
首先,你可以改变你的getConditions方法,看看发生了什么里面:
First you can change your getConditions method to see what's happening inside :
static IEnumerable<Func<int, bool>> getConditions()
{
yield return (a) => { Console.WriteLine(a + " modulo by 2"); return a % 2 == 0; };
yield return (a) => { Console.WriteLine(a + " modulo by 3"); Thread.Sleep(3000); return a % 3 == 0; };
}
如果你停止捕捉的foreach的变量,它的工作:
And if you stop capturing the foreach's variables, it will work :
static void filterAllDatas(ref IEnumerable<int> data, IEnumerable<Func<int, bool>> conditions)
{
List<int> filteredData = data.ToList();
List<Task> tasks = new List<Task>();
foreach (var item in data.AsParallel())
{
var i = item;
foreach (var condition in conditions.AsParallel())
{
var c = condition;
tasks.Add(Task.Factory.StartNew(() =>
{
if (c(i))
{
filteredData.Remove(i);
}
}));
}
}
Task.WaitAll(tasks.ToArray());
data = filteredData.AsEnumerable();
}
这篇关于越来越怪异的结果,而使用任务并行库?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!