【问题标题】:How to run two lists of tasks with different return types at the same time如何同时运行具有不同返回类型的两个任务列表
【发布时间】:2019-08-20 18:08:43
【问题描述】:

我正在尝试同时运行两个异步任务列表(具有不同的返回类型),但不知道该怎么做。

public void LoadPets()
{
    ServiceClient service = new ServiceClient();

    List<string> catNames = ...;
    List<string> dogNames = ...;

    List<Task<Cat>> catTasks = catNames.Select(x => service.GetCatAsync(x.Name));
    List<Task<Dog>> dogTasks = dogNames.Select(x => service.GetDogAsync(x.Name));

    foreach(object pet in Task.WhenAll(catTasks.Concat(dogTasks)).Result)
    {
       // Cast object
       // Do work with object.
    }
}

上面的代码不起作用,因为您无法连接不同类型的任务。但这些是从 Web 服务返回的类型。

我需要同时运行它们,因为抓猫大约需要 3 秒,抓狗也需要 3 秒钟。所以我最终总共等待了 6 秒,因为它们一个接一个地发生。

关于如何同时运行这两个任务列表的任何见解?

【问题讨论】:

  • 对Cat 和Dog 使用通用的基本类型或接口。

标签: c# .net async-await


【解决方案1】:

请注意,Task&lt;T&gt; 实际上继承自非泛型 Task,因此您将所有泛型任务转换为基类,如下所示:

var nonGenericTasks = catTasks
    .Cast<Task>()
    .Concat(dogTasks.Cast<Task>());

await Task.WhenAll(nonGenericTasks);

【讨论】:

  • 这让我可以连接它们。但是后来我不能做“.Result”,我怎么得到结果呢?
  • 您只需遍历原始任务并在每个任务上调用.Result。
  • 当我这样做时,它似乎会发出两次请求。 WhenAll 会按照我的意愿发出所有请求。但是当我遍历这些项目并执行 x.Result 时,它会再次运行请求(但这次是同步的,因为它遍历了每个项目)。另外我忘了提到我在执行此操作时不在异步方法中,所以我没有等待响应 .WhenAll(...).Wait()
  • 我想通了。我成了延期执行的牺牲品。我必须在我的选择语句末尾添加一个 ToList() ,然后一切正常。感谢您的所有帮助!
【解决方案2】:

您可以尝试以下方法:

 var tasks = new List<Task>()
 { 
     SomeMethod1Async(arg1, arg2),
     SomeMethod2Async(arg1)
 };

 await Task.WhenAll(tasks.ToArray());

 var result1 = ((Task<Result1>)tasks[0]).Result;
 var result2 = ((Task<Result2>)tasks[1]).Result;

其中 Result1 和 Result2 是 SomeMethod1Async 和 SomeMethod2Async 的返回类型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-17
    • 1970-01-01
    • 2019-04-15
    相关资源
    最近更新 更多