Esempio n. 1
0
 private void SetChangeSetProperty(RestierChangeSetProperty changeSetProperty)
 {
     foreach (var context in this.Contexts)
     {
         context.SetChangeSet(changeSetProperty);
     }
 }
Esempio n. 2
0
        /// <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));
        }