.NET C#async等待。当allall不等待任务时

时间:2014-06-24 15:23:45

标签: .net multithreading asynchronous async-await

我在.NET Framework 4.5中使用await / async / whenall。

时出现多线程问题

我通过调用循环来调用数千个线程。

List<Task<string>> t = new List<Task<string>>(); 
for (Row = 0; Row < lines.Count; Row++)
{        
    t.Add(AccessPaymentVault(Row, credentials, cts.Token));
}
string[] str_list = await Task.WhenAll(t.ToArray());

AccessPaymentVault功能用于连接保险库Web服务和检索信用卡信息。

async Task<string> AccessPaymentVault(int row, Credentials credentials, CancellationToken ct){
    var data = await Task.Run(() =>
    {
      return Tokenization.Retrieve(credentials, lines[row][CCColumnToken]);
    }, ct);

    return Encryptor.Decrypt(data);
}

Tokenization.Retrieve是最waited函数,它连接到webservice。 WhenAll似乎没有等待所有任务,因为结果中的某些记录随机丢失。 当我第一次运行时,它会检索所有记录。 在第二轮中,中间的一些记录丢失了。 在第三次运行中,第二次运行中丢失的记录存在,但缺少其他记录。

我想问题出在WhenAll但不确定。

非常感谢任何形式的帮助。

谢谢。

1 个答案:

答案 0 :(得分:2)

现在建议的启动新任务的方法是Task.Run而不是Task.Factory.StartNew,除非你需要更高级别的任务控制权。

在您的情况下,主要问题是结果类型将是Task,导致在此处进行一些嵌套。 但幸运的是有一种方法 - Task.Unwrap。

因此,如果您调用Task.Run - 在Task.Factory.StartNew下面,并自动调用Task.Unwrap。

查看此链接: http://blogs.msdn.com/b/pfxteam/archive/2011/10/24/10229468.aspx

另一篇好文章:StartNew is Dangerous

从评论中更新

在使用async / await方面,一切看起来都很好。 只是几个想法:

  1. Tokenization.Retrieve 中存在共享状态,由于多线程可能会被破坏
  2. 您可能会在 Tokenization.Retrieve
  3. 中吞下一些例外