越来越怪异的结果,而使用任务并行库? [英] Getting weird result while using Task Parallel Library?

查看:114
本文介绍了越来越怪异的结果,而使用任务并行库?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图做使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆