/// <summary> /// common handler for EndExecuteBatch & EndSaveChanges /// </summary> /// <typeparam name="T">derived type of the AsyncResult</typeparam> /// <param name="source">source object of async request</param> /// <param name="method">async method name on source object</param> /// <param name="asyncResult">the asyncResult being ended</param> /// <returns>data service response for batch</returns> internal static T EndExecute <T>(object source, string method, IAsyncResult asyncResult) where T : BaseAsyncResult { Util.CheckArgumentNull(asyncResult, "asyncResult"); T result = (asyncResult as T); if ((null == result) || (source != result.Source) || (result.Method != method)) { throw Error.Argument(Strings.Context_DidNotOriginateAsync, "asyncResult"); } Debug.Assert((result.CompletedSynchronously && result.IsCompleted) || !result.CompletedSynchronously, "CompletedSynchronously && !IsCompleted"); if (!result.IsCompleted) { // if the user doesn't want to wait forever, they should explictly wait on the handle with a timeout result.AsyncWaitHandle.WaitOne(); Debug.Assert(result.IsCompleted, "not completed after waiting"); } // Prevent EndExecute from being called more than once. if (System.Threading.Interlocked.Exchange(ref result.done, 1) != 0) { throw Error.Argument(Strings.Context_AsyncAlreadyDone, "asyncResult"); } // Dispose the wait handle. if (null != result.asyncWait) { System.Threading.Interlocked.CompareExchange(ref result.asyncWaitDisposeLock, new object(), null); lock (result.asyncWaitDisposeLock) { result.asyncWaitDisposed = true; Util.Dispose(result.asyncWait); } } if (result.IsAborted) { throw Error.InvalidOperation(Strings.Context_OperationCanceled); } if (null != result.Failure) { if (Util.IsKnownClientExcption(result.Failure)) { throw result.Failure; } throw Error.InvalidOperation(Strings.DataServiceException_GeneralError, result.Failure); } return(result); }
internal static T EndExecute <T>(object source, string method, IAsyncResult asyncResult) where T : BaseAsyncResult { Util.CheckArgumentNull <IAsyncResult>(asyncResult, "asyncResult"); T local = asyncResult as T; if (((local == null) || (source != local.Source)) || (local.Method != method)) { throw Error.Argument(Strings.Context_DidNotOriginateAsync, "asyncResult"); } if (!local.IsCompleted) { local.AsyncWaitHandle.WaitOne(); } if (Interlocked.Exchange(ref local.done, 1) != 0) { throw Error.Argument(Strings.Context_AsyncAlreadyDone, "asyncResult"); } if (local.asyncWait != null) { Interlocked.CompareExchange(ref local.asyncWaitDisposeLock, new object(), null); lock (local.asyncWaitDisposeLock) { local.asyncWaitDisposed = true; Util.Dispose <ManualResetEvent>(local.asyncWait); } } if (local.IsAborted) { throw Error.InvalidOperation(Strings.Context_OperationCanceled); } if (local.Failure == null) { return(local); } if (Util.IsKnownClientExcption(local.Failure)) { throw local.Failure; } throw Error.InvalidOperation(Strings.DataServiceException_GeneralError, local.Failure); }