concat result of three tasks in an async method in a proper way

孤街醉人 提交于 2019-12-06 07:36:33

am very new in async programming.

Then let's be careful and describe what is actually happening carefully.

I was wonder if there is any way to these tasks run simultaneously.

Don't think of tasks as running simultaneously, since that implies a concurrency model that might or might not be true. All you know about a task is that it will complete asynchronously.

Think about it like this: if you have some tasks like "pay my bills" and "mow my lawn", and "eat lunch" you might pay half your bills, then start mowing the lawn, then pause halfway through mowing the lawn, eat some lunch, pay a few more bills, and then finish mowing the lawn. You did the three tasks asynchronously but never did them concurrently. You were never mowing the lawn at the same time as eating your lunch. Sometimes asynchronous tasks really are running at the same time as other tasks, but not always, so don't think of tasks as running concurrently always.

I think because I used await twitterData should be done and after that next task will be started,

Correct. The key insight is await pauses an asynchronous workflow until the task is completed. Await does NOT make a call asynchronous. The task returned by the call is already an asynchronous workflow. An await simply means "if this task is not complete then find something else to do and come back here when it is complete".

So: how do you write your workflow so that you are not serializing the tasks? You put the awaits after the tasks are started. The right way to write your code is:

public async Task<IList<WebData>> GetAllAsync()
{
  var twitter = ProvideTwitterDataAsync();
  var facebook = ProvideFacebookDataAsync();
  var linkedin = ProvideLinkedinDataAsync();
  var twitterData = await twitter;
  var facebookData = await facebook;
  var linkedinData = await linkedin;
  return twitterData .Concat(facebookData ).Concat(linkedinData ).ToList();
}

Now the three tasks are started asynchronously, and then we pause the workflow until all three are completed, and then we concatenate the results.

Something like this should work.

public async Task<IList<WebData>> GetAllAsync()
{
    var twitter = ProvidetwitterDataAsync();
    var facebook = ProvidefacebookDataAsync();
    var linkedin = ProvidelinkedinDataAsync();
    return (await Task.WhenAll(twitter, facebook, linkedin)).SelectMany(d => d).ToList();
}

The 3 tasks can run concurrently, and then you wait for all of them, combine their results into a single list and return it.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!