.NETC#异步等待。Wheall不等待任务

.NETC#异步等待。Wheall不等待任务,.net,multithreading,asynchronous,async-await,.net,Multithreading,Asynchronous,Async Await,我在.NET Framework 4.5中使用wait/async/whenall时遇到多线程问题 我通过调用循环调用了数千个线程 List<Task<string>> t = new List<Task<string>>(); for (Row = 0; Row < lines.Count; Row++) { t.Add(AccessPaymentVault(Row, credentials, cts.Token)

我在.NET Framework 4.5中使用wait/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());
List t=newlist();
对于(行=0;行<行数;行++)
{        
t、 添加(AccessPaymentVault(行、凭证、cts.Token));
}
string[]str_list=wait Task.WhenAll(t.ToArray());
AccessPaymentVault功能用于连接vault 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);
}
async Task AccessPaymentVault(int行、凭据、取消令牌ct){
var data=wait Task.Run(()=>
{
返回标记化。检索(凭证,行[row][CCColumnToken]);
},ct);
返回加密机。解密(数据);
}
检索是等待时间最长的
函数,它连接到webservice。
WhenAll似乎没有等待所有任务,因为结果中的一些记录随机丢失。
当我第一次运行时,它检索所有记录。
在第二次运行中,中间的一些记录丢失了。
在第三次运行中,第二次运行中丢失的记录存在,但其他记录丢失

我想问题出在何时,但不确定

非常感谢任何形式的帮助


谢谢。

现在建议的启动新任务的方法是task。运行而不是task.Factory.StartNew,除非您需要对任务进行更高级别的控制

在您的例子中,主要的问题是结果类型将是Task,这会导致一些嵌套。 但幸运的是,有一个方法-Task.Unwrap

因此,如果调用Task.Run-down Task.Factory.StartNew和Task.Unwrap,则会自动调用

查看此链接:

还有一篇好文章:

根据评论更新

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

  • 标记化中存在共享状态。检索可能因多线程而中断
  • 您可能会在标记化中吞并一些异常。检索

  • 现在,启动新任务的建议方法是task.Run而不是task.Factory.StartNew,除非您需要对任务进行更高级别的控制

    在您的例子中,主要的问题是结果类型将是Task,这会导致一些嵌套。 但幸运的是,有一个方法-Task.Unwrap

    因此,如果调用Task.Run-down Task.Factory.StartNew和Task.Unwrap,则会自动调用

    查看此链接:

    还有一篇好文章:

    根据评论更新

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

  • 标记化中存在共享状态。检索可能因多线程而中断
  • 您可能会在标记化中吞并一些异常。检索

  • 现在,启动新任务的建议方法是task.Run而不是task.Factory.StartNew,除非您需要对任务进行更高级别的控制

    在您的例子中,主要的问题是结果类型将是Task,这会导致一些嵌套。 但幸运的是,有一个方法-Task.Unwrap

    因此,如果调用Task.Run-down Task.Factory.StartNew和Task.Unwrap,则会自动调用

    查看此链接:

    还有一篇好文章:

    根据评论更新

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

  • 标记化中存在共享状态。检索可能因多线程而中断
  • 您可能会在标记化中吞并一些异常。检索

  • 现在,启动新任务的建议方法是task.Run而不是task.Factory.StartNew,除非您需要对任务进行更高级别的控制

    在您的例子中,主要的问题是结果类型将是Task,这会导致一些嵌套。 但幸运的是,有一个方法-Task.Unwrap

    因此,如果调用Task.Run-down Task.Factory.StartNew和Task.Unwrap,则会自动调用

    查看此链接:

    还有一篇好文章:

    根据评论更新

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

  • 标记化中存在共享状态。检索可能因多线程而中断
  • 您可能会在标记化中吞并一些异常。检索

  • 这听起来很像。
    Tokenization.Retrieve()
    本身是否异步运行?否。这就是为什么我使用Task.Fask.StEngEnter这个函数。当你说“中间有一些记录丢失”时,你是什么意思?您使用什么代码来查看哪些记录?就使用异步/等待而言,一切看起来都很好。只有几个想法:1。Tokenization.Retrieve中存在共享状态,该状态可能因多线程2而中断。您可能会吞下令牌化中的一些异常。RetrieveMax,您解决了问题!出现异常,因为与服务器的连接太多。在catch部分,我再次尝试连接,问题解决了。写一个答案,我会接受你的答案。你救了我。谢谢!这听起来很像。
    Tokenization.Retrieve()
    本身是否异步运行?否。这就是为什么我使用Task.Fask.StEngEnter这个函数。当你说“中间有一些记录丢失”时,你是什么意思?您使用什么代码来查看哪些记录?就使用异步/等待而言,一切看起来都很好。只有几个想法:1。Tokenization.Retrieve中存在共享状态,该状态可能因多线程2而中断。您可能会吞下令牌化中的一些异常。RetrieveMax,您解决了问题!出现异常,因为与服务器的连接太多。在catch部分,我再次尝试连接,问题解决了。W