使用多线程将数据同时插入到列表中
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++)
我正在尝试优化一个小程序。所以这是基本的想法:
我有一组未过滤的数据,我想将其传递给一个函数,该函数将调用另一个函数两次,以进行数据过滤并插入到新列表中。第一次调用将从原始数组中获取数据,范围从 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++)