使用多线程将数据同时插入到列表中

Simoultanious data insertion into a list with multithreading

我正在尝试优化一个小程序。所以这是基本的想法:

我有一组未过滤的数据,我想将其传递给一个函数,该函数将调用另一个函数两次,以进行数据过滤并插入到新列表中。第一次调用将从原始数组中获取数据,范围从 0 => 数组长度的一半,第二个调用将执行相同的操作,但范围从一半到最后一项。这样,我应该将过滤后的数据同时插入到同一个列表中。插入完成后,筛选列表可以传递给程序的其余部分。这是代码:

    static void Main(string[] 
        {
            // the unfiltered list
            int[] oldArray = new int[6] {1,2,3,4,5,6};
            // filtered list
            List<int> newList= new List<int>();
            // Functions is my static class
            Functions.Insert(newList, oldArray )
            Continue_Program_With_Filtered_List(newList);
            // remaining functions...
        }

这里是函数 class:

public static class Functions
{
    public static void Insert(List<int> newList, int[] oldArray)
    {
        new Thread(() =>
        {
            Inserter(newList, oldArray, true);
        }).Start();
        new Thread(() =>
        {
            Inserter(newList, oldArray, false);
        }).Start();

        // I need to wait the result here of both threads
        // and make sure that every item from oldArray has been filtered
        // before I proceed to the next function in Main()
    }

    public static void Inserter(List<int> newList, int[] oldArray, bool countUp)
    {
        bool filterIsValid = false;
        int length = oldArray.Length;
        int halflen = (int)Math.Floor((decimal)length / 2);
        if (countUp)
        {
            // from half length to 0
            for (int i = 0; i < halflen; i++)
            {
                // filtering conditions here to set value of filterIsValid
                if(filterIsValid)
                    newList.Add(oldArray[i]);
            }
        }
        else
        {
            // from half length to full length
            for (int i = halflen + 1; i < length; i++)
            {
                // filtering conditions here to set value of filterIsValid
                if(filterIsValid)
                    newList.Add(oldArray[i]);
            }
        }
    }
}

所以问题是我必须 await Function.Insert() 完成每个线程,并在 之前遍历每个项目 newList 被传递到下一个函数主要的()。

我不知道如何在这样的事情上使用任务或异步方法。顺便说一下,这只是程序的概要。有帮助吗?

在您的情况下,使用 PLINQ 也可能是一个选项。

static void Main(string[] args)
{
    // the unfiltered list
    int[] oldArray = new int[6] { 1, 2, 3, 4, 5, 6 };
    // filtered list
    List<int> newList = oldArray.AsParallel().Where(filter).ToList();
    // remaining functions...
}

您也可以使用 AsOrdered() 来保持顺序


回到您最初的问题,您可以执行以下操作
注意:对原始代码进行最小更改的解决方案,无论是否有其他可能的优化
附加说明:请记住,仍然可能存在并发问题,具体取决于您对传递给该函数的参数所做的其他操作。

public static async Task Insert(List<int> newList, int[] oldArray)
{
    ConcurrentBag<int> concurrentBag = new ConcurrentBag<int>();
    var task1 = Task.Factory.StartNew(() =>
    {
        Inserter(concurrentBag, oldArray, true);
    });
    var task2 = Task.Factory.StartNew(() =>
    {
        Inserter(concurrentBag, oldArray, false);
    });
    await Task.WhenAll(task1, task2);
    newList.AddRange(concurrentBag);
}

public static void Inserter(ConcurrentBag<int> newList, int[] oldArray, bool countUp)
{
    //Same code
}

编辑:你的第二个for-loop错了,改成这个,否则你会丢一件

for (int i = halflen; i < length; i++)