Share data between threads

2019-08-02 20:06发布

问题:

I'm trying to implement an algorithm that should run in parallel using threads or tasks. The difficulty is that I want the threads/tasks to share their best results from time to time with all other threads.

The basic idea is this:

//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
        } 
    }
}

How can this be achieved using System.Threading or System.Threading.Tasks and is it true that tasks should not be used for long running operations?

Update: Clarification

It's not my problem to have a thread safe collection but to make the threads stop, publish result, wait until all other threads have publihed their results to and then go on again. All threads will run simultaneously. Cutting a long story short:

  1. Whats better for long running operations? Task or Thread or anything else?
  2. How to communicate between threads/taks to inform each of them about the state of all other assuming that the number of threads is set at runtime (depending on available cores).

Best Regards

Jay

回答1:

Look at the dollowing example.

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();
    }
}


回答2:

bomslang's response is not accurate. Cannot instantiate a new thread with ThreadStart, passing in Work method which requires a parameter to be passed in the above example. ParameterizedThreadStart would be more suitable. The sample code for the Main method would look more like this:

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

Note that 'work' is being passed into the ParameterizedThreadStart as the method for the new thread to execute, and the data required to pass in to the 'work' method is being passed in the call to start. The data must be passed as an object, so the work method will need to cast it back to the appropriate datatype as well. Lastly, there is also another approach to passing in data to a new thread via the use of anonymous methods.