Mohammad
Mohammad

Reputation: 589

parallel task and thread saftey in c#

I have two separate tasks and two independent operations in each. I think t0 is thread safe but I am not sure about t1. Is it correct? The performance of concurrent dictionary is awful and I need to insert a lot of data to the collection.

var t0 = new Task[2]
{
    Task.Factory.StartNew(()=>
    {
        list1=new sortedlist<int,int>(sortedlist1)
    }
    }),
    Task.Factory.StartNew(()=>
    {
        list2=new sortedlist<int,int>(sortedlist2)
    })
};
Task.WaitAll(t0)

var t1 = new Task[2]
{
    Task.Factory.StartNew(()=>
    {
        foreach (var item in sortedlist1)
        {
            list1.Add(item.Key, item.Value);
        }
    }),
    Task.Factory.StartNew(()=>
    {
        foreach (var item in sortedlist2)
        {
            list2.Add(item.Key, item.Value);
        }
    })
};
Task.WaitAll(t1)

Upvotes: 2

Views: 477

Answers (2)

dthorpe
dthorpe

Reputation: 36072

As written, this code doesn't work. The lists allocated in the first pair of tasks are not assigned to variables that are used by the second pair of tasks. Let's ignore that and just look at the general concepts here.

The two lists don't have to be allocated in separate threads to be used in separate threads. And you definitely do not need to waste effort allocating each list in a separate task. The lists can be allocated by the main thread, especially if the main thread is going to want to use the lists after the tasks are done. The only real issue is whether there is any possibility of one list being modified by two threads at the same time.

If list1 is only being read and written by task1, and list2 is only being read and written by task2, then you can do whatever you want to the lists in their respective tasks without any conflicts.

Use Task.WaitAll as you are already doing to wait for both tasks to complete. After both tasks are complete, the main thread can take control of list1 and list2 to make further modifications. One common follow-up operation after a set of parallel executed tasks such as this is to merge the work of the multiple tasks into a final output. (see "MapReduce")

Upvotes: 1

Ian Yates
Ian Yates

Reputation: 1354

This seems ok - you're not accessing the same variable across tasks. The tasks in t1[] won't run until the tasks from t0[] are finished.

You could use Parallel.Do() instead of making the tasks in the array and then waiting for them to finish - this makes your intentions more clear and avoids a lot of the array-based ceremony.

I assume you've made up up an example rather than this being actual code?

Upvotes: 0

Related Questions