2

Alright, I want to keep this short and precise, I'm trying to find the most efficient way to get a large amount of HttpWebRequests completed but I'm slightly confused, if I have a List of tasks and I use the Task.WaitAll function to await until all tasks have completed, is it overkill to make the Task (Action) in the list also an async task? Maybe I can explain myself better in code:

        for (int i = 0; i < 50; i++)
        {
            taskList.Add(Task.Run(() => DoSomething()));
        }
        Task.WaitAll(taskList.ToArray());

Ok so pretty simple, I have a for loop that'll run the DoSomething method on available threads within the ThreadPool, now let's take two different looks at how I can implement this DoSomething() function

public void DoSomething()
{
Send off the HttpWebRequest here, with no awaits or any async programming
}

OR

public Task<ResponseData> DoSomething()
{
Write the request here that awaits for responses, streams etc
}

If I am already sending the DoSomething function off to the Task.Run function doesnt that already mean it's running on it's own Thread in the ThreadPool ? meaning making the DoSomething function an actual task and implementing awaits/async functionality within that scope becomes redundant? wouldnt that just waste more resources?

7
  • Impossible to answer without more context. Does DoSomething() do anything other than make your HTTP request? Do you need for it to do something after the request is done? If all you're doing is the request, then you should use the async request API, return from DoSomething() the Task representing the request, and just add that to your list instead of using Task.Run(). If DoSomething() has more processing to do after the request, you should do the same, but you can await in it. Either way, it's unlikely you need Task.Run(). But who can tell, since you didn't share code. Commented May 4, 2017 at 2:35
  • So a function that returns a task is already accessing a thread on the threadpool as if I was passing a non-task returning function into Task.Run? So Task.Run(() => DoSomething()); would be the same as creating a function that returns a task? Commented May 4, 2017 at 2:38
  • "a function that returns a task is already accessing a thread on the threadpool?" -- not necessarily, no. But it is operating asynchronously, and that's what you care about in the code above. Don't confuse "asynchronous" with "concurrent" or "threaded". The two are closely related, but are not the same. There are asynchronous mechanisms that don't rely on an active thread. Commented May 4, 2017 at 2:39
  • So one last thing, iterating over a collection of objects and calling a function which returns a task in each iteration with awaits in that scope would give the same affect as adding Task.Run(() => NonTaskFunction) to a list of tasks and then awaiting it? But the more optimal, and 'proper' way of doing this would be to actually use the task api and implement the appropriate function yes? Iterating over a collection of objects in which the only thing I do is call the async task would give me the parralel/multithreaded aspect im looking for Commented May 4, 2017 at 2:43
  • So to conclude, having an async Task DoSomething() containing awaits and calling Task.Run(() => DoSomething is completely useless and unnecessary as a Task is already 'running' anyway as the function signature implies. I should only use Task.Run if I have a function or functions that need to be completed on a separate thread and said function isn't already a Task itself I guess Commented May 4, 2017 at 2:48

1 Answer 1

2

If I am already sending the DoSomething function off to the Task.Run function doesnt that already mean it's running on it's own Thread in the ThreadPool ? meaning making the DoSomething function an actual task and implementing awaits/async functionality within that scope becomes redundant?

Opposite - you are wasting resources when you using another thread (Task.Run) for the method which "do nothing" - waiting for the response.

await Task.Run(() => DoSomethingSynchronously) and await DoSomethingAsynchronously() are different things, because properly created async-await method will executes on the one thread.
In your case it will send request and return execution back to the caller. After response arrived it will continue execution after await.

So using Task.Run with methods which do nothing - only waiting for response become wasting of resources(threads).

Because your DoSomething method works with external resource (webervices), you don't need to worry about ThreadPool and threads at all. All tasks can be done asynchronously in one thread with async-await approach.

Sign up to request clarification or add additional context in comments.

5 Comments

I didnt understand fully what youre trying to say on the 3rd parahraph, but ill try to clarify. The are 2 options, either waiting for tasks 1-by-1 or just to wait everyone. waiting 1-by-1 is just if you really want to reduce resource useage or have something to do with the previous result of a task. Awaiting all means, "just finish everything until this point before moving on". Regardless to what you use, you MUST ALWAYS await an async task/s in the end of a method (unless moving it forward for another method) or else, youll have a racing condition which is bad.
@OriRefael, I wasn't talking about multiple tasks, In third paragraph I tried "rawly" explain that asynchronous method can be executed in one thread.
I wanted to clarify the approach of using async-await when one has multiple tasks.
@OriRefael - In case of two tasks, if second task not depend on result of first - then you can start both almost simultaneously and "await" when both tasks completes: await Task.WhenAll(new[] { getOneAsync(), getAnotherAsync() }). If second task depends on result of first then you will "await" first before starting second: var customerId = await getCustomerIdAsync(); await getOrderByCustomerIdAsync(customerId);
thats what I said :) Im not the OP nor someone who asked a question

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.