예제 #1
0
        /// <summary>
        /// Submit the specified <see cref="EntityChangeSet"/> to the DomainService, with the results of the operation
        /// being returned on the SubmitCompleted event args.
        /// </summary>
        /// <param name="changeSet">The changeset to submit. If the changeset is empty, an <see cref="InvalidOperationException"/> will
        /// be thrown.</param>
        /// <param name="cancellationToken"><see cref="CancellationToken"/> to be used for requesting cancellation</param>
        /// <returns>The results returned by the submit request.</returns>
        /// <exception cref="InvalidOperationException">The changeset is empty.</exception>
        protected override Task <SubmitCompletedResult> SubmitAsyncCore(EntityChangeSet changeSet, CancellationToken cancellationToken)
        {
            IEnumerable <ChangeSetEntry> submitOperations = changeSet.GetChangeSetEntries();

            TContract channel = this.ChannelFactory.CreateChannel();

            return(CallServiceOperation <SubmitCompletedResult>(channel,
                                                                "SubmitChanges",
                                                                new Dictionary <string, object>()
            {
                { "changeSet", submitOperations }
            },
                                                                (state, asyncResult) =>
            {
                try
                {
                    var returnValue = (IEnumerable <ChangeSetEntry>)EndServiceOperationCall(state, asyncResult);
                    return new SubmitCompletedResult(changeSet, returnValue ?? Enumerable.Empty <ChangeSetEntry>());
                }
                catch (FaultException <DomainServiceFault> fe)
                {
                    throw WebDomainClient <TContract> .GetExceptionFromServiceFault(fe.Detail);
                }
            }, cancellationToken));
        }
 /// <summary>
 /// Invokes an operation asynchronously.
 /// </summary>
 /// <param name="invokeArgs">The arguments to the Invoke operation.</param>
 /// <param name="cancellationToken"><see cref="CancellationToken"/> to be used for requesting cancellation</param>
 /// <returns>The results returned by the invocation.</returns>
 /// <exception cref="InvalidOperationException">The specified query does not exist.</exception>
 protected override Task <InvokeCompletedResult> InvokeAsyncCore(InvokeArgs invokeArgs, CancellationToken cancellationToken)
 {
     return(CallServiceOperation(invokeArgs.OperationName,
                                 invokeArgs.Parameters,
                                 (asyncResult) =>
     {
         IEnumerable <ValidationResult> validationErrors = null;
         object returnValue = null;
         try
         {
             returnValue = EndServiceOperationCall(this.ChannelFactory, asyncResult);
         }
         catch (FaultException <DomainServiceFault> fe)
         {
             if (fe.Detail.OperationErrors != null)
             {
                 validationErrors = fe.Detail.GetValidationErrors();
             }
             else
             {
                 throw WebDomainClient <TContract> .GetExceptionFromServiceFault(fe.Detail);
             }
         }
         return new InvokeCompletedResult(returnValue, validationErrors ?? Enumerable.Empty <ValidationResult>());
     },
                                 cancellationToken));
 }
예제 #3
0
        /// <summary>
        /// Gets the results of a submit.
        /// </summary>
        /// <param name="asyncResult">An asynchronous result that identifies a submit.</param>
        /// <returns>The results returned by the submit.</returns>
        protected sealed override SubmitCompletedResult EndSubmitCore(IAsyncResult asyncResult)
        {
            WebDomainClientAsyncResult <TContract> wcfAsyncResult = this.EndAsyncResult(asyncResult, AsyncOperationType.Submit, /* cancel */ false);
            MethodInfo      endSubmitMethod = wcfAsyncResult.EndOperationMethod;
            EntityChangeSet changeSet       = wcfAsyncResult.EntityChangeSet;

            IEnumerable <ChangeSetEntry> returnValue;

            try
            {
                try
                {
                    returnValue = (IEnumerable <ChangeSetEntry>)endSubmitMethod.Invoke(wcfAsyncResult.Channel, new object[] { wcfAsyncResult.InnerAsyncResult });
                }
                catch (TargetInvocationException tie)
                {
                    if (tie.InnerException != null)
                    {
                        throw tie.InnerException;
                    }

                    throw;
                }
                finally
                {
                    ((IChannel)wcfAsyncResult.Channel).Close();
                }
            }
            catch (FaultException <DomainServiceFault> fe)
            {
                throw WebDomainClient <TContract> .GetExceptionFromServiceFault(fe.Detail);
            }

            return(new SubmitCompletedResult(changeSet, returnValue ?? Enumerable.Empty <ChangeSetEntry>()));
        }
예제 #4
0
        /// <summary>
        /// Method called by the framework to begin an asynchronous query operation
        /// </summary>
        /// <param name="query">The query to invoke.</param>
        /// <param name="cancellationToken"><see cref="CancellationToken"/> to be used for requesting cancellation</param>
        /// <returns>The results returned by the query.</returns>
        /// <exception cref="InvalidOperationException">The specified query does not exist.</exception>
        protected override Task <QueryCompletedResult> QueryAsyncCore(EntityQuery query, CancellationToken cancellationToken)
        {
            TContract channel = this.ChannelFactory.CreateChannel();

            // Pass the query as a message property.
            using (OperationContextScope scope = new OperationContextScope((IContextChannel)channel))
            {
                if (query.Query != null)
                {
                    OperationContext.Current.OutgoingMessageProperties.Add(WebDomainClient <object> .QueryPropertyName, query.Query);
                }
                if (query.IncludeTotalCount)
                {
                    OperationContext.Current.OutgoingMessageProperties.Add(WebDomainClient <object> .IncludeTotalCountPropertyName, true);
                }

                return(CallServiceOperation <QueryCompletedResult>(channel,
                                                                   query.QueryName,
                                                                   query.Parameters,
                                                                   (state, asyncResult) =>
                {
                    IEnumerable <ValidationResult> validationErrors = null;
                    QueryResult returnValue = null;
                    try
                    {
                        returnValue = (QueryResult)EndServiceOperationCall(state, asyncResult);
                    }
                    catch (FaultException <DomainServiceFault> fe)
                    {
                        if (fe.Detail.OperationErrors != null)
                        {
                            validationErrors = fe.Detail.GetValidationErrors();
                        }
                        else
                        {
                            throw WebDomainClient <TContract> .GetExceptionFromServiceFault(fe.Detail);
                        }
                    }

                    if (returnValue != null)
                    {
                        return new QueryCompletedResult(
                            returnValue.GetRootResults().Cast <Entity>(),
                            returnValue.GetIncludedResults().Cast <Entity>(),
                            returnValue.TotalCount,
                            Enumerable.Empty <ValidationResult>());
                    }
                    else
                    {
                        return new QueryCompletedResult(
                            Enumerable.Empty <Entity>(),
                            Enumerable.Empty <Entity>(),
                            /* totalCount */ 0,
                            validationErrors ?? Enumerable.Empty <ValidationResult>());
                    }
                }
                                                                   , cancellationToken));
            }
        }
        /// <summary>
        /// Calls an operation on an already constructed WCF service channel
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="operationName">name of method/operation to call</param>
        /// <param name="parameters">parameters for the call</param>
        /// <param name="callback">callback responsible for casting return value and epr method error handling</param>
        /// <param name="cancellationToken"><see cref="CancellationToken"/> to be used for requesting cancellation</param>
        /// <returns>A <see cref="Task{TResult}"/> which will contain the result of the operation, exception or be cancelled</returns>
        protected virtual Task <TResult> CallServiceOperation <TResult>(string operationName,
                                                                        IDictionary <string, object> parameters,
                                                                        Func <IAsyncResult, TResult> callback, CancellationToken cancellationToken)
        {
            MethodInfo beginInvokeMethod = WebDomainClient <TContract> .ResolveBeginMethod(operationName);

            MethodInfo endInvokeMethod = WebDomainClient <TContract> .ResolveEndMethod(operationName);

            var taskCompletionSource = new TaskCompletionSource <TResult>();

            if (parameters == null)
            {
                parameters = new Dictionary <string, object>(2);
            }

            // Pass async operation related parameters.
            parameters.Add("callback", new AsyncCallback(delegate(IAsyncResult asyncResponseResult)
            {
                try
                {
                    TResult result = callback(asyncResponseResult);
                    taskCompletionSource.SetResult(result);
                }
#pragma warning disable CA1031 // Do not catch general exception types, we "rethrow it via task
                catch (CommunicationException) when(cancellationToken.IsCancellationRequested)
                {
                    taskCompletionSource.TrySetCanceled(cancellationToken);
                }
                catch (Exception ex)
#pragma warning restore CA1031 // Do not catch general exception types
                {
                    taskCompletionSource.TrySetException(ex);
                }
            }));
            parameters.Add("asyncState", /*userState*/ endInvokeMethod);

            // Call Begin** method
            // Handle any immediate CommunicationException which can be thrown directly from begin method
            // for some tests that perform invalid calls against localhost
            try
            {
                InvokeBeginMethod(beginInvokeMethod, ChannelFactory, parameters);
            }
            catch (CommunicationException ex)
            {
                // We might have aborted the channel due to cancellation
                if (cancellationToken.IsCancellationRequested)
                {
                    taskCompletionSource.TrySetCanceled(cancellationToken);
                }
                else
                {
                    taskCompletionSource.TrySetException(ex);
                }
            }

            return(taskCompletionSource.Task);
        }
예제 #6
0
        /// <summary>
        /// Gets the results of a query.
        /// </summary>
        /// <param name="asyncResult">An asynchronous result that identifies a query.</param>
        /// <returns>The results returned by the query.</returns>
        protected sealed override QueryCompletedResult EndQueryCore(IAsyncResult asyncResult)
        {
            WebDomainClientAsyncResult <TContract> wcfAsyncResult = this.EndAsyncResult(asyncResult, AsyncOperationType.Query, /* cancel */ false);
            MethodInfo endQueryMethod = (MethodInfo)wcfAsyncResult.EndOperationMethod;

            IEnumerable <ValidationResult> validationErrors = null;
            QueryResult returnValue = null;

            try
            {
                try
                {
                    returnValue = (QueryResult)endQueryMethod.Invoke(wcfAsyncResult.Channel, new object[] { wcfAsyncResult.InnerAsyncResult });
                }
                catch (TargetInvocationException tie)
                {
                    if (tie.InnerException != null)
                    {
                        throw tie.InnerException;
                    }

                    throw;
                }
                finally
                {
                    ((IChannel)wcfAsyncResult.Channel).Close();
                }
            }
            catch (FaultException <DomainServiceFault> fe)
            {
                if (fe.Detail.OperationErrors != null)
                {
                    validationErrors = fe.Detail.GetValidationErrors();
                }
                else
                {
                    throw WebDomainClient <TContract> .GetExceptionFromServiceFault(fe.Detail);
                }
            }

            if (returnValue != null)
            {
                return(new QueryCompletedResult(
                           returnValue.GetRootResults().Cast <Entity>(),
                           returnValue.GetIncludedResults().Cast <Entity>(),
                           returnValue.TotalCount,
                           Enumerable.Empty <ValidationResult>()));
            }
            else
            {
                return(new QueryCompletedResult(
                           new Entity[0],
                           new Entity[0],
                           /* totalCount */ 0,
                           validationErrors ?? Enumerable.Empty <ValidationResult>()));
            }
        }
예제 #7
0
        /// <summary>
        /// Invokes an operation asynchronously.
        /// </summary>
        /// <param name="invokeArgs">The arguments to the Invoke operation.</param>
        /// <param name="callback">The callback to invoke when the invocation has been completed.</param>
        /// <param name="userState">Optional user state that will be passed through on the <see cref="InvokeCompletedResult"/>.</param>
        /// <returns>An asynchronous result that identifies this invocation.</returns>
        /// <exception cref="InvalidOperationException">The specified query does not exist.</exception>
        protected sealed override IAsyncResult BeginInvokeCore(InvokeArgs invokeArgs, AsyncCallback callback, object userState)
        {
            MethodInfo beginInvokeMethod = WebDomainClient <TContract> .ResolveBeginMethod(invokeArgs.OperationName);

            MethodInfo endInvokeMethod = WebDomainClient <TContract> .ResolveEndMethod(invokeArgs.OperationName);

            // Pass operation parameters.
            ParameterInfo[] parameterInfos  = beginInvokeMethod.GetParameters();
            object[]        realParameters  = new object[parameterInfos.Length];
            int             parametersCount = (invokeArgs.Parameters == null) ? 0 : invokeArgs.Parameters.Count;

            for (int i = 0; i < parametersCount; i++)
            {
                realParameters[i] = invokeArgs.Parameters[parameterInfos[i].Name];
            }

            TContract channel = this.ChannelFactory.CreateChannel();
            WebDomainClientAsyncResult <TContract> wcfAsyncResult = WebDomainClientAsyncResult <TContract> .CreateInvokeResult(this, channel, endInvokeMethod, invokeArgs, callback, userState);

            // Pass async operation related parameters.
            realParameters[parameterInfos.Length - 2] = new AsyncCallback(delegate(IAsyncResult asyncResponseResult)
            {
                wcfAsyncResult.InnerAsyncResult = asyncResponseResult;
                wcfAsyncResult.Complete();
            });
            realParameters[parameterInfos.Length - 1] = userState;

            IAsyncResult asyncResult;

            try
            {
                asyncResult = (IAsyncResult)beginInvokeMethod.Invoke(channel, realParameters);
            }
            catch (TargetInvocationException tie)
            {
                if (tie.InnerException != null)
                {
                    throw tie.InnerException;
                }

                throw;
            }

            if (!asyncResult.CompletedSynchronously)
            {
                wcfAsyncResult.InnerAsyncResult = asyncResult;
            }
            return(wcfAsyncResult);
        }
        /// <summary>
        /// Initializes a new <see cref="WebDomainClientAsyncResult&lt;TContract&gt;"/> instance used for Invoke operations.
        /// </summary>
        /// <param name="domainClient">The <see cref="WebDomainClient&lt;TContract&gt;"/> associated with this result.</param>
        /// <param name="channel">The channel used to communicate with the server.</param>
        /// <param name="endOperationMethod">The method that completes an asynchronous operation.</param>
        /// <param name="invokeArgs">The arguments to the Invoke operation.</param>
        /// <param name="callback">Optional <see cref="AsyncCallback"/> to invoke upon completion.</param>
        /// <param name="asyncState">Optional user state information that will be passed to the <paramref name="callback"/>.</param>
        /// <exception cref="ArgumentNullException">if <paramref name="domainClient"/> is null.</exception>
        /// <exception cref="ArgumentNullException">if <paramref name="endOperationMethod"/> is null.</exception>
        private WebDomainClientAsyncResult(WebDomainClient <TContract> domainClient, TContract channel, MethodInfo endOperationMethod, InvokeArgs invokeArgs, AsyncCallback callback, object asyncState)
            : base(domainClient, invokeArgs, callback, asyncState)
        {
            if (channel == null)
            {
                throw new ArgumentNullException("channel");
            }

            if (endOperationMethod == null)
            {
                throw new ArgumentNullException("endOperationMethod");
            }

            this._endOperationMethod = endOperationMethod;
            this._channel            = channel;
        }
        /// <summary>
        /// Initializes a new <see cref="WebDomainClientAsyncResult&lt;TContract&gt;"/> instance used for Submit operations.
        /// </summary>
        /// <param name="domainClient">The <see cref="WebDomainClient&lt;TContract&gt;"/> associated with this result.</param>
        /// <param name="channel">The channel used to communicate with the server.</param>
        /// <param name="endOperationMethod">The method that completes an asynchronous operation.</param>
        /// <param name="entityChangeSet">The Submit operation <see cref="EntityChangeSet"/>.</param>
        /// <param name="changeSetEntries">The collection of <see cref="ChangeSetEntry"/>s to submit.</param>
        /// <param name="callback">Optional <see cref="AsyncCallback"/> to invoke upon completion.</param>
        /// <param name="asyncState">Optional user state information that will be passed to the <paramref name="callback"/>.</param>
        /// <exception cref="ArgumentNullException">if <paramref name="domainClient"/> is null.</exception>
        /// <exception cref="ArgumentNullException">if <paramref name="endOperationMethod"/> is null.</exception>
        private WebDomainClientAsyncResult(WebDomainClient <TContract> domainClient, TContract channel, MethodInfo endOperationMethod, EntityChangeSet entityChangeSet, IEnumerable <ChangeSetEntry> changeSetEntries, AsyncCallback callback, object asyncState)
            : base(domainClient, entityChangeSet, callback, asyncState)
        {
            if (channel == null)
            {
                throw new ArgumentNullException("channel");
            }

            if (endOperationMethod == null)
            {
                throw new ArgumentNullException("endOperationMethod");
            }

            this._endOperationMethod = endOperationMethod;
            this._channel            = channel;
            this._changeSetEntries   = changeSetEntries;
        }
예제 #10
0
        /// <summary>
        /// Submit the specified <see cref="EntityChangeSet"/> to the DomainService, with the results of the operation
        /// being returned on the SubmitCompleted event args.
        /// </summary>
        /// <param name="changeSet">The changeset to submit. If the changeset is empty, an <see cref="InvalidOperationException"/> will
        /// be thrown.</param>
        /// <param name="callback">The callback to invoke when the submit has been executed.</param>
        /// <param name="userState">Optional state that will flow through to the SubmitCompleted event</param>
        /// <returns>An asynchronous result that identifies this submit.</returns>
        /// <exception cref="InvalidOperationException">The changeset is empty.</exception>
        /// <exception cref="InvalidOperationException">The specified query does not exist.</exception>
        protected sealed override IAsyncResult BeginSubmitCore(EntityChangeSet changeSet, AsyncCallback callback, object userState)
        {
            MethodInfo beginSubmitMethod = WebDomainClient <TContract> .ResolveBeginMethod("SubmitChanges");

            MethodInfo endSubmitMethod = WebDomainClient <TContract> .ResolveEndMethod("SubmitChanges");

            IEnumerable <ChangeSetEntry> submitOperations = changeSet.GetChangeSetEntries();

            TContract channel = this.ChannelFactory.CreateChannel();
            WebDomainClientAsyncResult <TContract> wcfAsyncResult = WebDomainClientAsyncResult <TContract> .CreateSubmitResult(this, channel, endSubmitMethod, changeSet, submitOperations.ToList(), callback, userState);

            object[] parameters =
            {
                submitOperations,
                new AsyncCallback(delegate(IAsyncResult asyncResponseResult)
                {
                    wcfAsyncResult.InnerAsyncResult = asyncResponseResult;
                    wcfAsyncResult.Complete();
                }),
                userState
            };

            IAsyncResult asyncResult;

            try
            {
                asyncResult = (IAsyncResult)beginSubmitMethod.Invoke(channel, parameters);
            }
            catch (TargetInvocationException tie)
            {
                if (tie.InnerException != null)
                {
                    throw tie.InnerException;
                }

                throw;
            }

            if (!asyncResult.CompletedSynchronously)
            {
                wcfAsyncResult.InnerAsyncResult = asyncResult;
            }
            return(wcfAsyncResult);
        }
        /// <summary>
        /// Method called by the framework to begin an asynchronous query operation
        /// </summary>
        /// <param name="query">The query to invoke.</param>
        /// <param name="cancellationToken"><see cref="CancellationToken"/> to be used for requesting cancellation</param>
        /// <returns>The results returned by the query.</returns>
        /// <exception cref="InvalidOperationException">The specified query does not exist.</exception>
        protected override Task <QueryCompletedResult> QueryAsyncCore(EntityQuery query, CancellationToken cancellationToken)
        {
            return(CallServiceOperation <QueryCompletedResult>(query.QueryName,
                                                               query.Parameters,
                                                               (asyncResult) =>
            {
                IEnumerable <ValidationResult> validationErrors = null;
                QueryResult returnValue = null;
                try
                {
                    returnValue = (QueryResult)EndServiceOperationCall(this.ChannelFactory, asyncResult);
                }
                catch (FaultException <DomainServiceFault> fe)
                {
                    if (fe.Detail.OperationErrors != null)
                    {
                        validationErrors = fe.Detail.GetValidationErrors();
                    }
                    else
                    {
                        throw WebDomainClient <TContract> .GetExceptionFromServiceFault(fe.Detail);
                    }
                }

                if (returnValue != null)
                {
                    return new QueryCompletedResult(
                        returnValue.GetRootResults().Cast <Entity>(),
                        returnValue.GetIncludedResults().Cast <Entity>(),
                        returnValue.TotalCount,
                        Enumerable.Empty <ValidationResult>());
                }
                else
                {
                    return new QueryCompletedResult(
                        Enumerable.Empty <Entity>(),
                        Enumerable.Empty <Entity>(),
                        /* totalCount */ 0,
                        validationErrors ?? Enumerable.Empty <ValidationResult>());
                }
            }
                                                               , cancellationToken));
        }
예제 #12
0
        /// <summary>
        /// Gets the results of an invocation.
        /// </summary>
        /// <param name="asyncResult">An asynchronous result that identifies an invocation.</param>
        /// <returns>The results returned by the invocation.</returns>
        protected sealed override InvokeCompletedResult EndInvokeCore(IAsyncResult asyncResult)
        {
            WebDomainClientAsyncResult <TContract> wcfAsyncResult = this.EndAsyncResult(asyncResult, AsyncOperationType.Invoke, /* cancel */ false);
            MethodInfo endInvokeMethod = (MethodInfo)wcfAsyncResult.EndOperationMethod;

            IEnumerable <ValidationResult> validationErrors = null;
            object returnValue = null;

            try
            {
                try
                {
                    returnValue = endInvokeMethod.Invoke(wcfAsyncResult.Channel, new object[] { wcfAsyncResult.InnerAsyncResult });
                }
                catch (TargetInvocationException tie)
                {
                    if (tie.InnerException != null)
                    {
                        throw tie.InnerException;
                    }

                    throw;
                }
                finally
                {
                    ((IChannel)wcfAsyncResult.Channel).Close();
                }
            }
            catch (FaultException <DomainServiceFault> fe)
            {
                if (fe.Detail.OperationErrors != null)
                {
                    validationErrors = fe.Detail.GetValidationErrors();
                }
                else
                {
                    throw WebDomainClient <TContract> .GetExceptionFromServiceFault(fe.Detail);
                }
            }

            return(new InvokeCompletedResult(returnValue, validationErrors ?? Enumerable.Empty <ValidationResult>()));
        }
예제 #13
0
        /// <summary>
        /// Calls an operation on an already constructed WCF service channel
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="channel">WCF channel</param>
        /// <param name="operationName">name of method/operation to call</param>
        /// <param name="parameters">parameters for the call</param>
        /// <param name="callback">callback responsible for casting return value and epr method error handling</param>
        /// <param name="cancellationToken"><see cref="CancellationToken"/> to be used for requesting cancellation</param>
        /// <returns>A <see cref="Task{TResult}"/> which will contain the result of the operation, exception or be cancelled</returns>
        protected virtual Task <TResult> CallServiceOperation <TResult>(TContract channel, string operationName,
                                                                        IDictionary <string, object> parameters,
                                                                        Func <object, IAsyncResult, TResult> callback, CancellationToken cancellationToken)
        {
            MethodInfo beginInvokeMethod = WebDomainClient <TContract> .ResolveBeginMethod(operationName);

            MethodInfo endInvokeMethod = WebDomainClient <TContract> .ResolveEndMethod(operationName);

            // Pass operation parameters.
            ParameterInfo[] parameterInfos  = beginInvokeMethod.GetParameters();
            object[]        realParameters  = new object[parameterInfos.Length];
            int             parametersCount = parameters == null ? 0 : parameters.Count;

            for (int i = 0; i < parametersCount; i++)
            {
                realParameters[i] = parameters[parameterInfos[i].Name];
            }

            var taskCompletionSource = new TaskCompletionSource <TResult>();
            CancellationTokenRegistration cancellationTokenRegistration = default;

            if (cancellationToken.CanBeCanceled)
            {
                cancellationTokenRegistration = cancellationToken.Register(state => { ((IChannel)state).Abort(); }, channel);
            }
            // Pass async operation related parameters.
            realParameters[realParameters.Length - 2] = new AsyncCallback(delegate(IAsyncResult asyncResponseResult)
            {
                cancellationTokenRegistration.Dispose();

                try
                {
                    TResult result = callback(channel, asyncResponseResult);
                    taskCompletionSource.SetResult(result);
                }
                catch (CommunicationException) when(cancellationToken.IsCancellationRequested)
                {
#if SILVERLIGHT || NET45
                    taskCompletionSource.SetCanceled();
#else
                    taskCompletionSource.TrySetCanceled(cancellationToken);
#endif
                }
#pragma warning disable CA1031 // Do not catch general exception types, we "rethrow it via task
                catch (Exception ex)
#pragma warning restore CA1031 // Do not catch general exception types
                {
                    taskCompletionSource.SetException(ex);
                }
                finally
                {
                    if (((IChannel)channel).State == CommunicationState.Faulted)
                    {
                        ((IChannel)channel).Abort();
                    }
                    else
                    {
                        ((IChannel)channel).Close();
                    }
                }
            });
            realParameters[realParameters.Length - 1] = /*userState*/ endInvokeMethod;

            // Call Begin** method
            InvokeMethod(beginInvokeMethod, channel, realParameters);
            return(taskCompletionSource.Task);
        }
 /// <summary>
 /// Creates a new <see cref="WebDomainClientAsyncResult&lt;TContract&gt;"/> used for Invoke operations.
 /// </summary>
 /// <param name="domainClient">The <see cref="WebDomainClient&lt;TContract&gt;"/> associated with this result.</param>
 /// <param name="channel">The channel used to communicate with the server.</param>
 /// <param name="endOperationMethod">The method that completes an asynchronous operation.</param>
 /// <param name="invokeArgs">The arguments to the Invoke operation.</param>
 /// <param name="callback">The <see cref="AsyncCallback"/> to invoke upon completion.</param>
 /// <param name="asyncState">Optional user state information that will be passed to the <paramref name="callback"/>.</param>
 /// <returns>A <see cref="WebDomainClientAsyncResult&lt;TContract&gt;"/> used for Invoke operations</returns>
 public static WebDomainClientAsyncResult <TContract> CreateInvokeResult(WebDomainClient <TContract> domainClient, TContract channel, MethodInfo endOperationMethod, InvokeArgs invokeArgs, AsyncCallback callback, object asyncState)
 {
     return(new WebDomainClientAsyncResult <TContract>(domainClient, channel, endOperationMethod, invokeArgs, callback, asyncState));
 }
 /// <summary>
 /// Creates a new <see cref="WebDomainClientAsyncResult&lt;TContract&gt;"/> used for Submit operations.
 /// </summary>
 /// <param name="domainClient">The <see cref="WebDomainClient&lt;TContract&gt;"/> associated with this result.</param>
 /// <param name="channel">The channel used to communicate with the server.</param>
 /// <param name="endOperationMethod">The method that completes an asynchronous operation.</param>
 /// <param name="entityChangeSet">The Submit operation <see cref="EntityChangeSet"/>.</param>
 /// <param name="changeSetEntries">The collection of <see cref="ChangeSetEntry"/>s to submit.</param>
 /// <param name="callback">The <see cref="AsyncCallback"/> to invoke upon completion.</param>
 /// <param name="asyncState">Optional user state information that will be passed to the <paramref name="callback"/>.</param>
 /// <returns>A <see cref="WebDomainClientAsyncResult&lt;TContract&gt;"/> used for Submit operations</returns>
 public static WebDomainClientAsyncResult <TContract> CreateSubmitResult(WebDomainClient <TContract> domainClient, TContract channel, MethodInfo endOperationMethod, EntityChangeSet entityChangeSet, IEnumerable <ChangeSetEntry> changeSetEntries, AsyncCallback callback, object asyncState)
 {
     return(new WebDomainClientAsyncResult <TContract>(domainClient, channel, endOperationMethod, entityChangeSet, changeSetEntries, callback, asyncState));
 }
예제 #16
0
        /// <summary>
        /// Method called by the framework to begin an asynchronous query operation
        /// </summary>
        /// <param name="query">The query to invoke.</param>
        /// <param name="callback">The callback to invoke when the query has been executed.</param>
        /// <param name="userState">Optional state associated with this operation.</param>
        /// <returns>An asynchronous result that identifies this query.</returns>
        /// <exception cref="InvalidOperationException">The specified query does not exist.</exception>
        protected sealed override IAsyncResult BeginQueryCore(EntityQuery query, AsyncCallback callback, object userState)
        {
            MethodInfo beginQueryMethod = WebDomainClient <TContract> .ResolveBeginMethod(query.QueryName);

            MethodInfo endQueryMethod = WebDomainClient <TContract> .ResolveEndMethod(query.QueryName);

            // Pass query parameters.
            ParameterInfo[] parameterInfos  = beginQueryMethod.GetParameters();
            object[]        realParameters  = new object[parameterInfos.Length];
            int             parametersCount = (query.Parameters == null) ? 0 : query.Parameters.Count;

            for (int i = 0; i < parametersCount; i++)
            {
                realParameters[i] = query.Parameters[parameterInfos[i].Name];
            }

            TContract channel = this.ChannelFactory.CreateChannel();

            WebDomainClientAsyncResult <TContract> wcfAsyncResult = WebDomainClientAsyncResult <TContract> .CreateQueryResult(this, channel, endQueryMethod, callback, userState);

            // Pass async operation related parameters.
            realParameters[parameterInfos.Length - 2] = new AsyncCallback(delegate(IAsyncResult asyncResponseResult)
            {
                wcfAsyncResult.InnerAsyncResult = asyncResponseResult;
                wcfAsyncResult.Complete();
            });
            realParameters[parameterInfos.Length - 1] = userState;

            IAsyncResult asyncResult;

            try
            {
                // Pass the query as a message property.
                using (OperationContextScope scope = new OperationContextScope((IContextChannel)channel))
                {
                    if (query.Query != null)
                    {
                        OperationContext.Current.OutgoingMessageProperties.Add(WebDomainClient <object> .QueryPropertyName, query.Query);
                    }
                    if (query.IncludeTotalCount)
                    {
                        OperationContext.Current.OutgoingMessageProperties.Add(WebDomainClient <object> .IncludeTotalCountPropertyName, true);
                    }

                    asyncResult = (IAsyncResult)beginQueryMethod.Invoke(channel, realParameters);
                }
            }
            catch (TargetInvocationException tie)
            {
                if (tie.InnerException != null)
                {
                    throw tie.InnerException;
                }

                throw;
            }

            if (!asyncResult.CompletedSynchronously)
            {
                wcfAsyncResult.InnerAsyncResult = asyncResult;
            }

            return(wcfAsyncResult);
        }