GIVE-ME-CHICKEN
GIVE-ME-CHICKEN

Reputation: 1269

Task.Run on method returning T VS method returning Task<T>

Scenario 1 - For each website in string list (_websites), the caller method wraps GetWebContent into a task, waits for all the tasks to finish and return results.

    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;
    }

Scenario 2 - For each website in string list (_websites), the caller method calls GetWebContent (returns Task< string >), waits for all the tasks to finish and return the results.

    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;
    }

Questions - Which way is the correct approach and why? How does each approach impact achieving asynchronous processing?

Upvotes: 0

Views: 551

Answers (2)

Oleg Karasik
Oleg Karasik

Reputation: 969

@René Vogt gave a great explanation.

There a minor 5 cents from my side.

In the second example there is not need to use async / await in GetWebContent method. You can simply return Task<string> (this would also reduce async depth).

Upvotes: 1

Ren&#233; Vogt
Ren&#233; Vogt

Reputation: 43886

With Task.Run() you occupy a thread from the thread pool and tell it to wait until the web content has been received.
Why would you want to do that? Do you pay someone to stand next to your mailbox to tell you when a letter arrives?

GetStringAsync already is asynchronous. The cpu has nothing to do (with this process) while the content comes in over the network.

So the second approach is correct, no need to use extra threads from the thread pool here.

Always interesting to read: Stephen Cleary's "There is no thread"

Upvotes: 6

Related Questions