private void SetChangeSetProperty(RestierChangeSetProperty changeSetProperty) { foreach (var context in this.Contexts) { context.SetChangeSet(changeSetProperty); } }
/// <summary> /// Asynchronously sends the request. /// </summary> /// <param name="handler">The handler for processing a message.</param> /// <returns>The task object that contains the batch response.</returns> public override async Task <ODataBatchResponseItem> SendRequestAsync(RequestDelegate handler) { Ensure.NotNull(handler, nameof(handler)); var changeSetProperty = new RestierChangeSetProperty(this) { ChangeSet = new ChangeSet(), }; SetChangeSetProperty(changeSetProperty); var contentIdToLocationMapping = new Dictionary <string, string>(); var responseTasks = new List <Task <Task <HttpContext> > >(); foreach (var context in this.Contexts) { // Since exceptions may occure before the request is sent to RestierController, // we must catch the exceptions here and call OnChangeSetCompleted, // so as to avoid deadlock mentioned in Github Issue #82. var tcs = new TaskCompletionSource <HttpContext>(); var task = ODataBatchRequestItem.SendRequestAsync(handler, context, contentIdToLocationMapping) .ContinueWith( t => { if (t.Exception != null) { var taskEx = (t.Exception.InnerExceptions != null && t.Exception.InnerExceptions.Count == 1) ? t.Exception.InnerExceptions.First() : t.Exception; changeSetProperty.Exceptions.Add(taskEx); changeSetProperty.OnChangeSetCompleted(); tcs.SetException(taskEx.Demystify()); } else { tcs.SetResult(context); } return(tcs.Task); }, context.RequestAborted); responseTasks.Add(task); } // the responseTasks will be complete after: // - the ChangeSet is submitted // - the responses are created and // - the controller actions have returned await Task.WhenAll(responseTasks).ConfigureAwait(false); var returnContexts = new List <HttpContext>(); foreach (var responseTask in responseTasks) { var returnContext = responseTask.Result.Result; if (returnContext.Response.IsSuccessStatusCode()) { returnContexts.Add(returnContext); } else { returnContexts.Clear(); returnContexts.Add(returnContext); return(new ChangeSetResponseItem(returnContexts)); } } return(new ChangeSetResponseItem(returnContexts)); }