0

I have problem with multi threading in .NET Framework 4.5 with await/async/whenall.

I called thousands of threads by calling in loop.

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 Function is used for connecting vault web service and retrieve credit card information.

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 is the most waited function and it connects to webservice. WhenAll seems to be not waiting all tasks because some records in the result are randomly missing. When I first run, it retrieves all records. In second run, some records in the middle are missing. In third run, the missing records in second run was there but other records are missing.

I guess the problem is in WhenAll but not sure about it.

Any form of help is very appreciated.

Thank you.

sean
  • 1,644
  • 1
  • 15
  • 14
  • This sounds a lot like http://stackoverflow.com/q/23936521/120955. Does `Tokenization.Retrieve()` act asynchronously by itself? – StriplingWarrior Jun 24 '14 at 15:43
  • No it doesn't. That's why I used Task.Factory.StartNew for this function. – sean Jun 24 '14 at 15:47
  • When you say "some records in the middle are missing," what do you mean? What code are you using to see which records are there? – StriplingWarrior Jun 24 '14 at 16:28
  • It is populating csv file. So I can see the records missing easily. – sean Jun 24 '14 at 16:46
  • I mean rather than missing records, missing fields would be more correct expression. AccessPaymentVault function is used for retrieving credit card details, but some of them doesn't return. I tried debugging. When I debug the code, everything is there( I can see every records. perhaps it is because of delay in step by step debugging?). But when I execute, some cc details are missing. – sean Jun 24 '14 at 16:52
  • 3
    in terms of using async/await everything looks fine. Just a couple of ideas: 1. there is a shared state in Tokenization.Retrieve which might be broken because of multithreading 2. you might swallow some exceptions inside the Tokenization.Retrieve – Max Jun 24 '14 at 19:08
  • So TRUE! I swallowed an exception in Retrieve function when returning. – sean Jun 24 '14 at 19:14
  • 1
    Max, you solved the problem! There was an exception raising because too many connections to the server. In catch section, I tried connecting again and it was solved. Write an answer and I will accept yours as answer. You saved me. thanks a lot! – sean Jun 24 '14 at 19:26

1 Answers1

3

Nowadays the suggested way of starting a new task is Task.Run instead of Task.Factory.StartNew, unless you need a higher level of the control over the Task.

In your case, the main problem is that the result type will be Task, cause some nesting here. But luckily there is a way - Task.Unwrap.

So if you call the Task.Run - underneath Task.Factory.StartNew and the Task.Unwrap are called automatically.

Check out this link: http://blogs.msdn.com/b/pfxteam/archive/2011/10/24/10229468.aspx

And another good article: StartNew is Dangerous

Update from comments

In terms of using async/await everything looks fine. Just a couple of ideas:

  1. there is a shared state in Tokenization.Retrieve which might be broken because of multithreading
  2. you might swallow some exceptions inside the Tokenization.Retrieve
Max
  • 601
  • 8
  • 21
  • Max, I appreciate your answer. I changed the startNew into Task.Run but it had same problem. I am editing the question into Task.Run for no more confusion. – sean Jun 24 '14 at 15:52
  • the link to msdn blogs seems broken. here is the web archive version: https://web.archive.org/web/20150221140040/http://blogs.msdn.com/b/pfxteam/archive/2011/10/24/10229468.aspx – Pramodh Aug 07 '23 at 21:36