private async Task <KinveyMultiInsertResponse <T> > HandleNetworkRequestAsync(IList <T> entities) { var kinveyDataStoreResponse = new KinveyMultiInsertResponse <T> { Entities = HelperMethods.Initialize <T>(default(T), entities.Count), Errors = new List <Error>() }; var updateRequests = new Dictionary <int, NetworkRequest <T> >(); var entitiesToMultiInsert = new List <T>(); var initialIndexes = new List <int>(); for (var index = 0; index < entities.Count; index++) { var idToken = JObject.FromObject(entities[index])["_id"]; if (idToken != null && !string.IsNullOrEmpty(idToken.ToString())) { var updateRequest = Client.NetworkFactory.buildUpdateRequest(Collection, entities[index], idToken.ToString()); updateRequests.Add(index, updateRequest); } else { entitiesToMultiInsert.Add(entities[index]); initialIndexes.Add(index); } } var multiInsertNetworkResponse = new KinveyMultiInsertResponse <T> { Entities = new List <T>(), Errors = new List <Error>() }; if (entitiesToMultiInsert.Count > 0) { var countOfMultiInsertOperations = Math.Ceiling(entitiesToMultiInsert.Count / (double)Constants.NUMBER_LIMIT_OF_ENTITIES); var currentIndex = 0; var currentCountOfMultiInsertOperations = 0; while (currentCountOfMultiInsertOperations < countOfMultiInsertOperations) { var tasks = new List <Task <KinveyMultiInsertResponse <T> > >(); for (var index = currentCountOfMultiInsertOperations; index < currentCountOfMultiInsertOperations + 10; index++) { if (index < countOfMultiInsertOperations) { tasks.Add(HandleMultiInsertRequestAsync(entitiesToMultiInsert.Skip(index * Constants.NUMBER_LIMIT_OF_ENTITIES).Take(Constants.NUMBER_LIMIT_OF_ENTITIES).ToList())); } } await Task.WhenAll(tasks.ToArray()).ConfigureAwait(false); foreach (var task in tasks) { for (var index = 0; index < task.Result.Entities.Count; index++) { multiInsertNetworkResponse.Entities.Add(task.Result.Entities[index]); if (task.Result.Entities[index] == null) { var error = task.Result.Errors?.Find(er => er.Index == index); if (error != null) { var newError = new Error { Index = currentIndex, Code = error.Code, Errmsg = error.Errmsg }; multiInsertNetworkResponse.Errors.Add(newError); } } currentIndex++; } } currentCountOfMultiInsertOperations += 10; } } for (var index = 0; index < multiInsertNetworkResponse.Entities.Count; index++) { kinveyDataStoreResponse.Entities[initialIndexes[index]] = multiInsertNetworkResponse.Entities[index]; var error = multiInsertNetworkResponse.Errors?.Find(er => er.Index == index); if (error != null) { var newError = new Error { Index = initialIndexes[index], Code = error.Code, Errmsg = error.Errmsg }; kinveyDataStoreResponse.Errors.Add(newError); } } foreach (var updateRequest in updateRequests) { T updatedEntity = default(T); try { updatedEntity = await updateRequest.Value.ExecuteAsync().ConfigureAwait(false); } catch (Exception ex) { var error = new Error { Index = updateRequest.Key, Code = 0, Errmsg = ex.Message }; kinveyDataStoreResponse.Errors.Add(error); } kinveyDataStoreResponse.Entities[updateRequest.Key] = updatedEntity; } kinveyDataStoreResponse.Errors.Sort((x, y) => x.Index.CompareTo(y.Index)); return(kinveyDataStoreResponse); }