List<int> data=new List<int>();
foreach(int id in ids){
var myThread=new Thread(new ThreadStart(Work));
myThread.Start(id);
}
Work(){
}
Method Work对收到的ID进行一些处理,然后将结果添加到数据列表中?如何从每个线程向集合中添加数据?我的代码怎么样?谢谢
答案 0 :(得分:8)
如果您使用的是.NET 4,我强烈建议您使用Parallel Extensions。例如:
var list = ids.AsParallel()
.Select(Work)
.ToList();
其中Work
是:
public int Work(int id)
{
...
}
以便它可以适当地接收id
。如果您不热衷于方法转换,可以添加lambda表达式:
var list = ids.AsParallel()
.Select(id => Work(id))
.ToList();
无论哪种方式,这都将避免创建比实际需要更多的线程,并且无需自己管理锁定就可以处理线程安全方面的问题。
答案 1 :(得分:1)
首先,您需要使用锁保护多线程访问。其次,您需要将参数传递给您的线程(或者使用可以捕获局部变量的lambda;请注意,如果捕获循环变量,它将在循环期间更改值,因此您应该拥有本地副本)。 / p>
object collectionLock = new object();
List<int> data = new List<int>();
foreach (int id in ids)
{
Thread t = new Thread(Worker);
t.Start(id);
}
void Worker(object o)
{
int id = (int)o;
lock(collectionLock)
{
data.Add(id);
}
}
答案 2 :(得分:0)
您可以从线程传递和检索数据(使用回调)。请参阅MSDN article。
示例:强>
public class SomeClass
{
public static List<int> data = new List<int>();
public static readonly object obj = new object();
public void SomeMethod(int[] ids)
{
foreach (int id in ids)
{
Work w = new Work();
w.Data = id;
w.callback = ResultCallback;
var myThread = new Thread(new ThreadStart(w.DoWork));
myThread.Start();
}
}
public static void ResultCallback(int d)
{
lock (obj)
{
data.Add(d);
}
}
}
public delegate void ExampleCallback(int data);
class Work
{
public int Data { get; set; }
public ExampleCallback callback;
public void DoWork()
{
Console.WriteLine("Instance thread procedure. Data={0}", Data);
if (callback != null)
callback(Data);
}
}