2

我有两个独立的任务和两个独立的操作。我认为 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)
4

2 回答 2

1

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

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

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

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

于 2012-11-19T07:16:19.033 回答
0

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

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

我假设您已经编造了一个示例,而不是实际代码?

于 2012-11-19T07:14:34.723 回答