Task.Run on方法返回T VS方法返回Task <t>

时间:2018-06-05 13:26:24

标签: c# .net async-await asynchronous

场景1 - 对于字符串列表中的每个网站(_websites),调用方法将GetWebContent包装到任务中,等待所有任务完成并返回结果。

    private async Task<string[]> AsyncGetUrlStringFromWebsites()
    {
        List<Task<string>> tasks = new List<Task<string>>();

        foreach (var website in _websites)
        {
            tasks.Add(Task.Run(() => GetWebsiteContent(website)));
        }

        var results = await Task.WhenAll(tasks);

        return results;
    }

    private string GetWebContent(string url)
    {
        var client = new HttpClient();

        var content = client.GetStringAsync(url);

        return content.Result;
    }

场景2 - 对于字符串列表中的每个网站(_websites),调用方法调用GetWebContent(返回Task&lt; string&gt;),等待所有任务完成并返回结果。< / p>

    private async Task<string[]> AsyncGetUrlStringFromWebsites()
    {
        List<Task<string>> tasks = new List<Task<string>>();

        foreach (var website in _websites)
        {
            tasks.Add(GetWebContent(website));
        }

        var results = await Task.WhenAll(tasks);

        return results;
    }

    private async Task<string> GetWebContent(string url)
    {
        var client = new HttpClient();

        var content = await client.GetStringAsync(url);

        return content;
    }

问题 - 哪种方法是正确的?为什么?每种方法如何影响实现异步处理?

2 个答案:

答案 0 :(得分:6)

使用Task.Run(),您将占用线程池中的一个线程,并告诉它等待直到收到Web内容。
你为什么想这么做?当你收到信件时,你是否支付某人站在你的邮箱旁边告诉你?

GetStringAsync已经是异步的。当内容通过网络传入时,cpu与此过程无关(

所以第二种方法是正确的,不需要在这里使用线程池中的额外线程。

总是很有意思:Stephen Cleary's "There is no thread"

答案 1 :(得分:2)

@RenéVogt给出了很好的解释。

我身边有5美分。

在第二个示例中,无需在async方法中使用await / GetWebContent。您只需返回Task<string>(这也会减少async深度。)