使用不同的线程更改列表中的每个元素

时间:2016-06-23 11:59:39

标签: c# concurrency task

我有以下伪代码:

public void Associar(List<Data> dados)
{
   List<Task> tasks = new List<Task>();
   foreach(dado in dados)
   {
       tasks.Add(AdicionarAsync(dado));
   }
   Task.WaitAll(tasks.ToArray());

   Debug.WriteLine(dados.Select(e => e.Colecao).Sum(e => e.Count));
}

public async Task<List<Foo>> ConsultarNoBanco()
{
   //make request 
   //here the result is OK
   return result;
}

public async Task AdicionarAsync(Data dado)
{
   dado.Colecao = await ConsultarNoBanco();
   //Here the result (dado.Colecao) is wrong
   //If I modify the code to ConsultarNoBanco().Result everything works fine
}

此代码的输出必须始终为411.但是,每次调用方法Associar()时,结果都会更改。使用线程安全列表来更改多线程集合中的每个项目的最佳方法是什么?

2 个答案:

答案 0 :(得分:0)

使用Parallel.ForEach();修改列表中的条目。 它将为您管理并发和线程。

您还可以使用break

e.Break();

答案 1 :(得分:0)

当前的答案/评论说明了您需要管理并发性的事情,因为您使用任务/线程修改列表中的条目。恕我直言这是不正确的,因为在Data对象上进行的修改很好 - 每个任务只修改指定的Data对象。此时不需要同步。

另一方面,您的方法ConsultarNoBanco正在从多个任务/线程执行,同时执行。由于您没有在方法中显示代码,因此我们无法对此进行任何说明。但我的印象是这种方法不是线程安全的。特别是因为该方法没有接收到Data对象,因此我只能假设它正在做与Data对象无关的事情。

你能展示方法ConsultarNoBanco的代码吗?它是线程安全的吗?你提到一个请求,请求处理程序是线程安全的吗?