在线程之间共享数据

时间:2011-07-31 03:48:02

标签: c# .net multithreading task-parallel-library

我正在尝试实现一个应该使用线程或任务并行运行的算法。困难在于我希望线程/任务不时与所有其他线程共享最佳结果。

基本理念是:

//Accessible from each thread
IProducerConsumerCollection<MyObject> _bestObjects;

//Executed in each thread
DoSomeWork(int n){
    MyObject localObject;
    for(var i = 0; i < n; i++){
        //Do some calculations and store results in localObject
        if((i/n)%0.5 == 0)
        {
            //store localObject in _bestObjects
            //wait until each thread has stored its result in _bestObjects
            //get the best result from _bestObjects and go on
        } 
    }
}

如何使用System.Threading或System.Threading.Tasks实现这一点,并且任务不应该用于长时间运行的操作吗?

更新:澄清

拥有一个线程安全集合但是让线程停止,发布结果,等待所有其他线程都将其结果发布到然后再继续,这不是我的问题。所有线程将同时运行。 长话短说:

  1. 长期运营的情况会更好吗?任务或线程或其他什么?
  2. 如何在线程/目标之间进行通信,以便在假设线程数在运行时设置(取决于可用内核)时,告知每个线程/所有其他状态。
  3. 最好的问候

2 个答案:

答案 0 :(得分:0)

请看以下示例。

public class Worker
{
    public SharedData state;
    public void Work(SharedData someData)
    {
        this.state = someData;
        while (true) ;
    }

}

public class SharedData {
    X myX;
    public getX() { ... }
    public setX(anX) { ... }    
}

public class Sharing
{
    public static void Main()
    {
        SharedData data = new SharedDate()
        Worker work1 = new Worker(data);
        Worker work2 = new Worker(data);
        Thread thread = new Thread(new ThreadStart(work1.Work));
        thread.start();
        Thread thread2 = new Thread(new ThreadStart(work2.Work));
        thread2.start();
    }
}

答案 1 :(得分:0)

bomslang的反应不准确。无法使用ThreadStart实例化新线程,传入Work方法,该方法需要在上面的示例中传递参数。 ParameterizedThreadStart会更合适。 Main方法的示例代码看起来更像是:

public class Sharing
{
    public static void Main()
    {
        SharedData data = new SharedDate()
        Worker work1 = new Worker(data);
        Worker work2 = new Worker(data);
        Thread thread = new Thread(new ParameterizedThreadStart(work1.Work));
        thread.start(someData);
        Thread thread2 = new Thread(new ParameterizedThreadStart(work2.Work));
        thread2.start(someData);
    }
}

请注意,'work'作为新线程执行的方法传递给ParameterizedThreadStart,传递给'work'方法所需的数据正在调用start中传递。数据必须作为对象传递,因此工作方法也需要将其转换回适当的数据类型。最后,还有另一种方法是通过使用匿名方法将数据传递给新线程。