Your method is not asynchronous. Assuming your GetUser method already starts an asynchronous task, Parallel.ForEach would use additional threads just to start off your tasks, which is probably not what you want.
Instead, what you probably want to do is to start all of the tasks and wait for them to finish:
public static IEnumerable<JObject> GetUsers(IEnumerable<string> usersUids, Field fields) { var tasks = usersUids.Select( uid => { var parameters = new NameValueCollection { {"uids", uid}, {"fields", FieldsUtils.ConvertFieldsToString(fields)} }; return GetUser(parameters); } ).ToArray(); Task.WaitAll(tasks); var result = new JObject[tasks.Length]; for (var i = 0; i < tasks.Length; ++i) result[i] = tasks[i].Result; return result; }
If you also want to start them in parallel you can use PLINQ:
var tasks = usersUids.AsParallel().AsOrdered().Select( uid => { var parameters = new NameValueCollection { {"uids", uid}, {"fields", FieldsUtils.ConvertFieldsToString(fields)} }; return GetUser(parameters); } ).ToArray();
Both code snippets preserve relative ordering of uids and returned objects - result[0] corresponds to usersUids[0], etc.