【发布时间】:2018-12-17 12:26:13
【问题描述】:
我正在尝试优化一个小程序。所以这是基本的想法:
我有一个未经过滤的数据数组,我想将它传递给一个函数,该函数将调用另一个函数,两次,用于数据过滤和插入新列表。第一次调用将从原始数组中获取数据,范围为 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...
}
这里是函数类:
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]);
}
}
}
}
所以问题是我必须等待 Function.Insert() 来完成每个线程,并在将 newList 传递给 Main() 中的下一个函数之前 传递每个项目。
我不知道如何在这样的事情上使用任务或异步方法。顺便说一下,这只是程序的概要。有什么帮助吗?
【问题讨论】:
-
.NET 已经有并发集合,例如 ConcurrentQueue 和 ConcurrentDictionary。如果你想让
List线程安全,你必须在尝试读/写时使用lock。您无法通过条件检查确保线程安全。List的修改方法不是线程安全的 -
另一种选择是从每个线程返回一个列表,并在线程完成工作后合并这些列表。所以你不必关心并发写入,但它期望项目顺序符合所需的顺序。
-
@PanagiotisKanavos 你说的是真的。即使有这么小的模拟数据,插入也已经很狡猾了。不知道 ConcurrentQueue 命名空间。谢谢
-
@user743414 忘了说,顺序无关紧要。该列表将被插入到字典中,然后在需要时进行搜索。或者,我将使用上面的答案,并尝试立即将其插入并发字典。
标签: c# multithreading list asynchronous synchronous