0

Currently I am using a Parallel foreach loop, the code looks something like this.

Parallel.ForEach(ListData, toPost =>
            {
                try
                {
                    string result = toPost.Post();
                    if (!result.Contains("Exception"))
                    {
                        this.Dispatcher.Invoke(() =>
                        {
                            updateLog("Success");
                        });
                    }

                }
                catch (Exception ex)
                {
                    this.Dispatcher.Invoke(() =>
                   {
                       updateLog("Exception: " + ex.Message);
                   });
                }

            });

However it is going a bit slow. I am trying to fire off as many of these HttpWebRequests as possible, and the only thing I care about is the response and that is to update the UI. I read about async requests, but am confused as to how they are actually 'async' and the different between Parallel and Async.

I found somebody who asked something similar. Getting the Response of a Asynchronous HttpWebRequest

Could I just put it in a for loop? Going back to my example if I implemented async, would it be something like

foreach(toPost in ListData)
{
   var task = toPost.PostAsync();
   // do something with task
}

From what I understand about async, this would continue looping regardless of whether or not PostAsync() returned anything yet? If so, can I use async inside a parallel foreach loop and that would be even quicker?

Sorry If these questions are stupid. I'm quite new to all of this and am looking for the quickest way to do this, am just having trouble quite understanding the difference between async and parallel and which is better for my situation.

Randy
  • 1

1 Answers1

0

Parallel.ForEach uses a thread pool thread to execute the body of your code. Since the bulk of the time your thread is waiting for the I/O operation to complete it is a rather wasteful use of an expensive thread, a thread that could have been doing something else instead.

await on an async I/O operation starts the I/O call but does not wait for it to complete. In fact there is no thread for async I/O due to the use of I/O Completion Ports. It's a rather complex scenario best explained in the former link.

However, do not mix await and Parallel.ForEach, the latter is not compatible with the tasks and threading of the former.

If you have multiple operations you want to perform asynchronoursly, then you could use Task.WhenAll or take a look at TPL DataFlow.

From what I understand about async, this would continue looping regardless of whether or not PostAsync() returned anything yet? If so, can I use async inside a parallel foreach loop and that would be even quicker?

No. For each iteration of the loop you await the Task and so the next operation want execute until the task completes. Essentially the loop is serial and so are the tasks. If you want all the tasks to execute in parallel, add them to say a List<Task> and call await Task.WhenAll(tasks).