C# 多个线程向列表提供数据<;列表<;字符串>&燃气轮机;到主线程;多线程
我有多个线程创建一个C# 多个线程向列表提供数据<;列表<;字符串>&燃气轮机;到主线程;多线程,c#,multithreading,list,concurrency,.net-3.5,C#,Multithreading,List,Concurrency,.net 3.5,我有多个线程创建一个公共列表列表,并用数据填充它。完成所有线程后,我想使用list.AddRange()组合主线程的listOfLits中多个线程的所有列表 因此,如果我有三个线程,每个线程的listOfLists有10个元素,那么主线程的listOfLists将有30个元素。只需简单地添加它们,mainthread对象就必须有线程插入的所有数据 如果我在列表中使用静态关键字,它将非常有效。我想做的就是摆脱static 这里有一个小例子 我创建了一个简单的Person对象(主线程) 主线程调用一
公共列表列表
,并用数据填充它。完成所有线程后,我想使用list.AddRange()
组合主线程的listOfLits
中多个线程的所有列表
因此,如果我有三个线程,每个线程的listOfLists
有10个元素,那么主线程的listOfLists
将有30个元素。只需简单地添加它们,mainthread对象就必须有线程插入的所有数据
如果我在列表
中使用静态
关键字,它将非常有效。我想做的就是摆脱static
这里有一个小例子
listOfLists
listOfLists
添加到静态listOfLists
班级人员
{
公共字符串名称;
公开名单私人宠物;
公共列表listOfLists=新列表();
public static List familyPets=new List();
公共人物(字符串n){name=n;}//构造函数
公众人物(){}
public void startMultiThreading()
{
List_threads=新列表();
对于(int i=0;i<3;i++)
{
Person多线程Person=newperson(“multi:+i);//创建新的Person
Thread t=新线程(multiThreadPerson.fill_List);//创建新线程
t、 Name=multiThreadPerson.Name;//用PersonName命名线程
列出所有线程。添加(t);
list_threads[i].Start();//新用户正在调用fill_list()
}
对于(int i=0;iDebug.WriteLine(e));
}
}
公共空白填写清单()
{
privatePet=新列表();
锁(家庭型)
{
对于(int i=0;i<20;i++)
{
添加(“dog:+Thread.CurrentThread.Name”);
privatePet.Add(“cat:+this.name”);
添加(私人宠物);
}
familyPets.AddRange(ListofList);//将所有ListofList添加到主线程ListofList
}//锁
}
}
我认为问题在于,填充数据和加入数据都使用同一类“Person”
Person p = new Person("mainThread");
从不调用fill_List(),也不使用变量privatePet和listofList
在不过度修改代码的情况下,一个简单的解决方案是添加一个新的构造函数:
public Person(String n, List<List<String>> pRefFamilyPets) { name = n; familyPets = pRefFamilyPets; } //constructor
我无法遵循逻辑,但这似乎避免了使用STATIC,因为您正在将引用传递给其他线程。我认为问题在于您在填充数据和连接数据时使用了相同的类“Person”
Person p = new Person("mainThread");
从不调用fill_List(),也不使用变量privatePet和listofList
在不过度修改代码的情况下,一个简单的解决方案是添加一个新的构造函数:
public Person(String n, List<List<String>> pRefFamilyPets) { name = n; familyPets = pRefFamilyPets; } //constructor
我无法遵循逻辑,但这似乎避免了使用STATIC,因为您正在将引用传递给其他线程。以及
ThreadStart
委托,您可以使用参数化ThreadStart
委托创建线程,然后Start()
带有一个重载,该重载接受单个对象参数。您可以使用需要传递到线程的delgate的任何信息创建该对象,在本例中,delgate只是您所关心的列表的单个列表
还要注意的是,您的锁定太宽了,以至于只允许一个这样的线程执行任何操作,从而击败了多线程。您希望他们自己处理只有他们才能处理的事情(privatePet
,例如,在本例中,i
,因为每个线程都有自己的独立视图。thread.CurrentThread
是静态的,但线程是安全的(否则将毫无意义)虽然这个
不是线程安全的,是共享的,但是在零线程写入字符串字段时,让多个线程从字符串字段中读取是安全的(您可以通过将名称
设置为只读
使其更加安全,因为这样您就可以100%放心地知道,只要查看该代码,就不会有任何内容写入它,除非它故意弄乱东西
public void fill_List(object targetList)
{
List<List<String>> familyPets = (List<List<String>>)targetList;
List<List<String>> listOfLists = new List<List<String>>();//we'll use our own local one of these thanks, as it's just this thread's concern write now.
privatePet = new List<string>();
for (int i = 0; i < 20; i++)
{
privatePet.Add("dog :" + Thread.CurrentThread.Name);
privatePet.Add("cat :" + this.name);
listOfLists.Add(privatePet);
}
//note you don't need to lock until you are doing something
//that hits on something that other threads might hit on.
//otherwise you've just got each thread locked for their entire
//duration and you might as well just do the whole thing
//in one thread.
lock (familyPets)
{
familyPets.AddRange(listOfLists); //adding up all listOfLists to the mainthread listOfLists
}
}
除了
ThreadStart
委托外,您还可以使用ParameterizedThreadStart
委托创建线程,然后使用Start()
带有一个重载,该重载接受一个对象参数。您可以使用需要传递到线程的delgate中的任何信息创建该对象,在本例中,delgate只是您所关心的列表的单个列表
还请注意,您的锁定范围太广,以至于只能让一个这样的线程执行任何操作,从而破坏了多线程。您希望他们自己处理只有他们才能处理的事情(privatePet
,例如,在本例中,i
,因为每个线程都有自己的独立视图。thread.CurrentThr
public void fill_List(object targetList)
{
List<List<String>> familyPets = (List<List<String>>)targetList;
List<List<String>> listOfLists = new List<List<String>>();//we'll use our own local one of these thanks, as it's just this thread's concern write now.
privatePet = new List<string>();
for (int i = 0; i < 20; i++)
{
privatePet.Add("dog :" + Thread.CurrentThread.Name);
privatePet.Add("cat :" + this.name);
listOfLists.Add(privatePet);
}
//note you don't need to lock until you are doing something
//that hits on something that other threads might hit on.
//otherwise you've just got each thread locked for their entire
//duration and you might as well just do the whole thing
//in one thread.
lock (familyPets)
{
familyPets.AddRange(listOfLists); //adding up all listOfLists to the mainthread listOfLists
}
}
list_threads[i].Start(whateverTheListIsCalled);
Enumerable.Range(0, 3).AsParallel().WithDegreeOfParallelism(3).Select(n => {
var list = new List<string>();
list.Add(n + ": One");
list.Add(n + ": Two");
list.Add(n + ": Three");
return list;
}).ToList();
Enumerable.Range(0, 3).AsParallel().WithDegreeOfParallelism(3).Select(n => {
var list = new List<string>();
list.Add(n + ": One");
list.Add(n + ": Two");
list.Add(n + ": Three");
return list;
}).Aggregate((a, b) => a.Union(b).ToList());