0

I am using Parallel.invoke for executing multiple tasks but it returns the response before all the operations are completed. I want to use await keyboard while calling methods as all the methods are async but it doesn't allow me to do so. Also I know I can use Task.WhenAll() but the requirement is to use Parallel.Invoke so is there any way to achieve my goal?

var list = new List<string>();
var myArr = new string[] { "usa", "eng", "fra"  };

Parallel.Invoke(() =>
{
    myArr.Select(i => {
        var data= MyMethod(i);
        list.Add(1, data);
    });
});

and the MyMethod implementation

public async Task<string> GetName(string country)
{
    var data = await _db.GetAll().FindAsync(country).Capital;
    return data;
}

Also I have another question is there any better approach to call the method 3 or 4 times inside Parallel.Invoke?

arnt
  • 8,949
  • 5
  • 24
  • 32
Ask
  • 3,076
  • 6
  • 30
  • 63
  • `Parallel.Invoke()` waits for all the tasks that it spawns to complete. You must have a mistake in your code somewhere. – Matthew Watson Jul 20 '18 at 10:39
  • What are the signatures of the methods that you're calling? – Enigmativity Jul 20 '18 at 10:41
  • Thanks for the response. let me recheck my code. Also another thing that I forgot to mention in question that I want add the response returned by async method in a list so I can do that without await keyword? – Ask just now – Ask Jul 20 '18 at 10:42
  • 2
    If those methods return a `Task` then `Parallel.Invoke` will return immediately because it doesn't care if the tasks are running or not. – Enigmativity Jul 20 '18 at 10:45
  • method1 is basically an async method that returns a response from http request. I want to add that response in list like {var a = method1(); list.Add(a)} – Ask Jul 20 '18 at 10:49
  • Can you show the whole code? The request and everything? I think I have a solution that would encompass the entire thing that would be better than doing just this one bit. – Enigmativity Jul 20 '18 at 10:52
  • @Enigmativity, I have updated my question. Can you review? – Ask Jul 20 '18 at 11:03
  • `myArr.Select` does nothing – Backs Jul 20 '18 at 11:09
  • @Backs, you're right. Actually I was working on that part but I thought first I should fix the first issue than I'll go to the next one – Ask Jul 20 '18 at 11:10
  • @Ask - You mentioned a HTTP request, but the code doesn't show it. Your code shows a `_db` but you don't say what it is. There's a `MyMethod` call, but you don't provide details for that. We need a [mcve] please. – Enigmativity Jul 20 '18 at 13:34

2 Answers2

1
var list = new List<string>();
var myArr = new string[] { "usa", "eng", "fra" };

var tasks = myArr.Select(o => GetName(o));

var results = await Task.WhenAll(tasks);
Backs
  • 24,430
  • 5
  • 58
  • 85
1

Also I know I can use Task.WhenAll() but the requirement is to use Parallel.Invoke so is there any way to achieve my goal?

Your requirement to use Parallel.Invoke is likely wrong.

Your GetName method is IO bound. There is very little benefit in threading this. All you're doing is spawning more threads that you then have to await the async result of. This is less efficient than just looping.

It would make more sense to run this asynchronously. That way you don't use unnecessary threads but you use your main thread more effectively. You can do this using Task.WhenAll:

var list = new List<string>();
var myArr = new string[] { "usa", "eng", "fra"  };
IEnumerable<Task<string>> myTasks = myArr.Select(i => {
                    GetName(i);
                });

await Task.WhenAll(myTasks);
foreach(Task<string> task in myTasks)
{
     string result = task.Result;
}
Liam
  • 27,717
  • 28
  • 128
  • 190
  • thanks, another thing I might need to add the GetName() response in dictionary instead of a list. So is this approach fine for(int i = 0 i <= myTasks.Length -1; i++) { dictionary.Add(myArr(i), myTasks[i]); } Or is there any better approach? – Ask Jul 20 '18 at 11:43
  • You'd need to process the `Dictionary` after your async calls have returned I think. But it's not clear what your asking in comments. Probably ask a new question – Liam Jul 20 '18 at 12:15