【问题标题】:Trying to use Task.WhenAll with Task<string> not working尝试将 Task.WhenAll 与 Task<string> 一起使用不起作用
【发布时间】:2020-07-15 19:49:46
【问题描述】:

我正在尝试将多个资源组合在一个集合中(下面的变量)。 GetLocations2 返回一个任务,我希望能够将其添加到任务结果集合(同样是 s 变量)。但是,由于以下错误,我无法将任务结果添加到集合中:

错误 CS1503 参数 1:无法从“字符串”转换为 'System.Threading.Tasks.Task'

调用

public static async Task<string> WebRequest2(Uri uri)
{
    using (var client = new WebClient())
    {
        var result = await client.OpenReadTaskAsync(uri).ConfigureAwait(false);

        using (var sr = new StreamReader(result))
        {
            return sr.ReadToEnd();
        }
    }
}

来电者

private static async Task GetLocations2()
{
    var s = new List<Task<string>>();

    foreach (var lob in _lobs)
    {
        var r = await Helper.WebRequest2(new Uri(lob));
  
        var x = Helper.DeserializeResponse<SLICS>(r);

        s.Add(r); //Getting red squiggly here
    }

    //var w = await Task.WhenAll();

}

【问题讨论】:

    标签: c# asynchronous async-await task-parallel-library


    【解决方案1】:

    在将任务添加到列表之前您不需要await,它基本上会解开由Helper.WebRequest2创建的Task(也等待Task完成,因此您原始代码中的任务将按顺序执行) :

    private static async Task GetLocations2()
    {
        var s = new List<Task<string>>();
    
        foreach (var lob in _lobs)
        {
            var r = Helper.WebRequest2(new Uri(lob));
      
            // var x = Helper.DeserializeResponse<SLICS>(r); this should be done after Task.WhenAll 
            // or using `ContinueWith`
    
            s.Add(r); 
        }
    
        var w = await Task.WhenAll(s);
    
    }
    

    【讨论】:

    • 但您仍在等待答案
    • @MindSwipe 谢谢你,愚蠢的我,以为我已经删除了它)
    • 没问题,有时我们所有人都会遇到,现在它完美地回答了这个问题+1
    • @GuruStron,我不是要编辑你的答案,我以为我在编辑我的。
    • @Rod NP,很高兴为您提供帮助 =)
    【解决方案2】:

    您还可以将这两个操作包装在 async lambda 中,以避免重复两次:

    private static async Task GetLocations2()
    {
        IEnumerable<SLICS> w = await Task.WhenAll(_lobs.Select(async lob =>
        {
            var r = await Helper.WebRequest2(new Uri(lob));
            return Helper.DeserializeResponse<SLICS>(r);
        }));
    }
    

    使用 Select 将枚举 lambda 表达式返回的所有 Tasks,然后 Task.WhenAll 将等待它们全部完成,然后解包结果。

    【讨论】:

    • _uri 中的 new Uri(_uri) 会变成 new Uri(_) 吗?
    • @Rod 您没有显示_uri 的定义位置。我认为这是一个不会改变的私有领域?在您的示例中,它实际上应该是 lob 吗?将 lambda 的参数命名为 _ 只是表明它没有在正文中使用。这只是个人喜好,因为它类似于丢弃。
    • 很抱歉我更新了 OP。你是对的,它应该是 lob 所以我想我可以将 _ 更改为实际变量,对吗?
    • @Rod 没问题;我已经相应地更新了我的答案。
    猜你喜欢
    • 1970-01-01
    • 2016-02-28
    • 2018-06-08
    • 2016-03-25
    • 2013-12-25
    • 2014-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多