使用线程 - 添加到集合

时间:2011-02-19 19:02:17

标签: c# multithreading

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进行一些处理,然后将结果添加到数据列表中?如何从每个线程向集合中添加数据?我的代码怎么样?谢谢

3 个答案:

答案 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);
        }

    }