c#中的并行任务和线程安全

时间:2012-11-19 06:57:52

标签: c# parallel-processing task-parallel-library

我有两个独立的任务,每个任务有两个独立的操作。我认为t0是线程安全的,但我不确定t1。这是对的吗?并发字典的性能很糟糕,我需要在集合中插入大量数据。

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)

2 个答案:

答案 0 :(得分:1)

如上所述,此代码不起作用。在第一对任务中分配的列表未分配给第二对任务使用的变量。让我们忽略它,只看这里的一般概念。

不必在单独的线程中分配这两个列表以在单独的线程中使用。而且你绝对不需要浪费精力在一个单独的任务中分配每个列表。列表可以由主线程分配,特别是如果主线程要在任务完成后要使用列表。唯一真正的问题是是否有可能同时由两个线程修改一个列表。

如果list1仅由task1读取和写入,并且list2仅由task2读取和写入,那么您可以在各自的任务中对列表执行任何操作而不会发生任何冲突。

使用Task.WaitAll,因为您已经在等待两个任务完成。两个任务完成后,主线程可以控制list1和list2进行进一步修改。在一组并行执行的任务之后的一个常见的后续操作是将多个任务的工作合并到最终输出中。 (参见“MapReduce”)

答案 1 :(得分:0)

这似乎没问题 - 你没有在任务中访问相同的变量。在完成t0 []的任务之前,t1 []中的任务将不会运行。

您可以使用Parallel.Do()而不是在数组中创建任务然后等待它们完成 - 这会使您的意图更加清晰,并避免大量基于阵列的仪式。

我假设你已经编造了一个例子而不是实际的代码?