【问题标题】:Task.WhenAny ContinueWith: Get argument?Task.WhenAny ContinueWith:获取参数?
【发布时间】:2015-10-21 08:23:40
【问题描述】:

我想执行一个任务列表,并在其中任何一个完成后执行一个同步操作,但我需要知道它是哪一个。

查看我的示例,并注意代码中的注释,前面有几行我不知道如何实现。

public async Task<bool> GreetAsync(string name)
{
  if (name == null)
    return false;

  await InternalGreeter.GreetAsync(name);
  return true;
}

public async Task GreetAllAsync()
{
  var tasks = UserNames.Select(un => GreetAsync(un)).ToList();

  while(tasks.Any())
  {
    var finished = await Task.WhenAny(tasks);

    if(finished.Result)
    {
      //Here's what I'd like to achieve
      var username = finished.Arguments[0];
      WriteLine($"User {username} has been greeted.");
    }

    tasks.Remove(finished);
  } 
}

基于this 示例。

在我的真实世界场景中,我有一个客户列表,我必须逐个遍历他们并根据他们的信用状态更新远程服务器(远程服务器不支持批量更新)。在他们每个人都更新后,我必须在我的数据库中标记该客户已获得认可。

【问题讨论】:

  • 那么,你的问题是什么?
  • 你做了什么,发生了什么?
  • 我认为你不能(应该?)这样做。为什么不直接UserNames.Select(un =&gt; GreetAsync(un)).ContinueWith(...).ToList();
  • Task 有一个 AsyncState 属性,表示它的状态对象,作为 Task 构造函数或 ContinueWith 中的第二个参数传递,但你没有使用任何一个。

标签: c# asynchronous async-await task


【解决方案1】:

您几乎从不想实际处理一个任务列表,因为它们是这样完成的。相反,只需引入更高级别的操作并将您的Task.WhenAny 重写为Task.WhenAll 以等待那些更高级别的操作。

public async Task<bool> GreetAsync(string name)
{
  if (name == null)
    return false;

  await InternalGreeter.GreetAsync(name);
  return true;
}

private async Task<bool> GreetAndReportGreetedAsync(string name)
{
  var result = await GreetAsync(name);
  WriteLine($"User {name} has been greeted.");
  return result;
}

public async Task GreetAllAsync()
{
  await Task.WhenAll(UserNames.Select(un => GreetAsync(un));
}

【讨论】:

  • GreetAndGreetAsync 可以是 lambda 表达式,还是有不需要专用方法的更好方法?顺便说一句,我已经更新了我的问题。
  • @Shimmy:当然,任何方法都可以是 lambda 表达式。我不认为它“更好”,但如果你喜欢它:await Task.WhenAll(UserNames.Select(async un =&gt; { if (await GreetAsync(un)) WriteLine($"User {un} has been greeted."); }));
【解决方案2】:

为什么不直接使用ContinueWith?像这样的:

public async Task GreetAllAsync(List<string> UserNames)
{
  var tasks = UserNames
    .Select(un => GreetAsync(un)
        .ContinueWith(x => {
            Console.WriteLine(un + " has been greeted");
        }));

    await Task.WhenAll(tasks);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-25
    • 1970-01-01
    • 2020-08-28
    • 1970-01-01
    • 2019-10-16
    • 1970-01-01
    相关资源
    最近更新 更多