private bool TrySetOperationInternal(Delegate op) { lock (_eventLock) { if (_isClosed) { throw new ObjectDisposedException("WorkerThread"); } if (_runningOp == null) { _runningOpCompleteEvent.Reset(); OperationDescriptor runningOp = new OperationDescriptor(op); _runningOp = runningOp; _opSet.Set(); _runningOpCompleteEvent.WaitOne(); Debug.Assert(runningOp.IsComplete, "Why isn't the running op complete?"); if (runningOp.ExceptionDispatchInfo != null) { runningOp.ExceptionDispatchInfo.Throw(); } return(true); } } return(false); }
public object Invoke(OperationDescriptor operation, object[] parameters) { using (var client = new HttpClient()) { var paramsHolder = operation.BoxParameterValues(parameters); var data = _serializer.Serialize(paramsHolder); using (var ms = new MemoryStream(data)) { var requestContent = new StreamContent(ms); var url = GetServiceUrl(operation); var requestTask = client.PostAsync(url, requestContent); var readDataTask = requestTask.Result.Content.ReadAsByteArrayAsync(); var responseContent = readDataTask.Result; if (operation.IsIterator) { return(ReadFromIterator(operation.ReturnType, responseContent)); } else { return(_serializer.Deserialize(operation.ReturnType, responseContent)); } } } }
private bool TrySetOperationInternalWithProgress(AsyncProgressOperation op, string text, CancellationTokenSource canTokenSource) { var waitLoop = new HostWaitLoop(text); lock (_eventLock) { if (_isClosed) { throw new ObjectDisposedException("WorkerThread"); } if (_runningOp == null) { _runningOpCompleteEvent.Reset(); OperationDescriptor runningOp = new OperationDescriptor(new AsyncOperation(() => { return(op(waitLoop)); })); _runningOp = runningOp; _opSet.Set(); waitLoop.Wait(_runningOpCompleteEvent, canTokenSource); Debug.Assert(runningOp.IsComplete, "Why isn't the running op complete?"); if (runningOp.ExceptionDispatchInfo != null) { runningOp.ExceptionDispatchInfo.Throw(); } return(true); } } return(false); }
public void ExecuteOverloadedOperations() { string actionName = "RetrieveProduct"; string actionTitle = "Microsoft.Test.OData.Services.AstoriaDefaultService." + actionName; var contextWrapper = this.CreateWrappedContext(); Product product = contextWrapper.Execute <Product>(new Uri(this.ServiceUri + "Product(-10)", UriKind.Absolute)).Single(); OperationDescriptor productOperationDescriptor = contextWrapper.GetEntityDescriptor(product).OperationDescriptors.Single(); Assert.AreEqual(this.ServiceUri + "Product(-10)/" + actionTitle, productOperationDescriptor.Target.AbsoluteUri, true); Assert.AreEqual(this.ServiceUri + ActionOverloadingQueryTests.MetadataPrefix + actionName, productOperationDescriptor.Metadata.AbsoluteUri, true); OrderLine orderLine = contextWrapper.Execute <OrderLine>(new Uri(this.ServiceUri + "OrderLine(OrderId=-10,ProductId=-10)", UriKind.Absolute)).Single(); OperationDescriptor orderLineOperationDescriptor = contextWrapper.GetEntityDescriptor(orderLine).OperationDescriptors.Single(); Assert.AreEqual(this.ServiceUri + "OrderLine(OrderId=-10,ProductId=-10)/" + actionTitle, orderLineOperationDescriptor.Target.AbsoluteUri, true); Assert.AreEqual(this.ServiceUri + ActionOverloadingQueryTests.MetadataPrefix + actionName, orderLineOperationDescriptor.Metadata.AbsoluteUri, true); // service operation int serviceOperationResult = contextWrapper.Execute <int>(new Uri(this.ServiceUri + actionName, UriKind.Absolute), "POST", true).Single(); // actions int productActionResult = contextWrapper.Execute <int>(productOperationDescriptor.Target, "POST", true).Single(); int orderLineActionResult = contextWrapper.Execute <int>(orderLineOperationDescriptor.Target, "POST", true).Single(); }
static SubSession() { MyFlagProperty = DataPropertyDescriptor <bool> .Register("MyFlag", typeof(SubSession)); DoSubActionOperation = OperationDescriptor.Register("DoSubAction", typeof(SubSession)); DoOtherSubActionOperation = OperationDescriptor.Register("DoOtherSubAction", typeof(SubSession)); OnStaticConstruction(); }
private void VerifyLinks(Dictionary <string, string> expectedValues, IEnumerable <OperationDescriptor> actualDescriptors) { foreach (KeyValuePair <string, string> expected in expectedValues) { OperationDescriptor od = actualDescriptors.Where(d => d.Metadata.AbsoluteUri.Equals(this.ServiceUri + expected.Key, StringComparison.InvariantCultureIgnoreCase)).First(); Assert.AreEqual(this.ServiceUri + expected.Value, od.Target.AbsoluteUri, true); } }
public static Exception DependencyInjection_InvalidOperationKind( OperationDescriptor descriptor) { return(new CodeGeneratorException( ErrorBuilder .New() .SetMessage("{0} is not a valid operation kind", descriptor.GetType()) .Build())); }
OperationModel ToOperationModel(OperationDescriptor operation) { return(new OperationModel { Factory = operation.Create, HttpMethod = GetHttpMethodForOperation(operation), Name = operation.Name }); }
private void CreateMethodImpl(string interfaceName, OperationDescriptor operationDescriptor) { MethodBuilder mb = _typeBuilder.DefineMethod( operationDescriptor.MethodInfo.Name, MethodAttributes.Public | MethodAttributes.Virtual, operationDescriptor.ReturnType, (from p in operationDescriptor.Parameters select p.ParameterType).ToArray()); var ilc = mb.GetILGenerator(); var localParams = ilc.DeclareLocal(typeof(object[])); //var localReturn = ilc.DeclareLocal(typeof(object)); var localReturn = ilc.DeclareLocal(operationDescriptor.ReturnType); var argTypes = operationDescriptor.Parameters; ilc.Emit(OpCodes.Nop); ilc.Emit(OpCodes.Ldc_I4, argTypes.Length); ilc.Emit(OpCodes.Newarr, typeof(object)); for (int i = 0; i < argTypes.Length; i++) { ilc.Emit(OpCodes.Dup); ilc.Emit(OpCodes.Ldc_I4, i); ilc.Emit(OpCodes.Ldarg, i + 1); Type argType = argTypes[i].ParameterType; if (argType.GetTypeInfo().IsValueType) { ilc.Emit(OpCodes.Box, argType); } ilc.Emit(OpCodes.Stelem_Ref); } ilc.Emit(OpCodes.Stloc, localParams); ilc.Emit(OpCodes.Ldsfld, _ServiceDescriptorFiledBuilder); ilc.Emit(OpCodes.Ldstr, operationDescriptor.Name); ilc.Emit(OpCodes.Ldloc, localParams); ilc.Emit(OpCodes.Call, Invoker); if (operationDescriptor.ReturnType.GetTypeInfo().IsValueType) { ilc.Emit(OpCodes.Unbox_Any, operationDescriptor.ReturnType); } ilc.Emit(OpCodes.Stloc, localReturn); ilc.Emit(OpCodes.Nop); ilc.Emit(OpCodes.Ldloc, localReturn); //ilc.Emit(OpCodes.Ldc_I4_6); //ilc.Emit(OpCodes.Ldc_I4_4); //ilc.Emit(OpCodes.Add); ilc.Emit(OpCodes.Ret); _typeBuilder.DefineMethodOverride(mb, operationDescriptor.MethodInfo); }
private string GetServiceUrl(OperationDescriptor operation) { var pathPattern = _configuration.GetServicePathPattern(); var host = _configuration.GetServiceHost(); var port = _configuration.GetServicePort(); var path = _pathManager.GetServicePath(operation.Service.Name, operation.Name, pathPattern); return($"http://{host}:{port}{path}"); }
// Inconsistent behavior when selecting namespace.* and action name // [TestMethod] // github issuse: #896 public void BaseDerivedTypeOverloadedActionsProjection() { string actionName = "UpdatePersonInfo"; for (int i = 0; i < 2; i++) { var contextWrapper = this.CreateWrappedContext(); if (i == 1) { contextWrapper.Format.UseJson(); } // base type instance, $select=ActionNmae Person person = contextWrapper.Execute <Person>(new Uri(this.ServiceUri + "Person(-1)?$select=PersonId," + actionName, UriKind.Absolute)).Single(); OperationDescriptor personOperationDescriptor = contextWrapper.GetEntityDescriptor(person).OperationDescriptors.Single(); Assert.AreEqual(this.ServiceUri + ActionOverloadingQueryTests.MetadataPrefix + actionName, personOperationDescriptor.Metadata.AbsoluteUri, true); Assert.AreEqual(this.ServiceUri + "Person(-1)/UpdatePersonInfo", personOperationDescriptor.Target.AbsoluteUri, true); // base type instance, $select=DerivedType/ActionName contextWrapper.Detach(person); person = contextWrapper.Execute <Person>(new Uri(this.ServiceUri + "Person(-1)?$select=PersonId," + ActionOverloadingQueryTests.EmployeeTypeName + "/" + actionName, UriKind.Absolute)).Single(); Assert.AreEqual(0, contextWrapper.GetEntityDescriptor(person).OperationDescriptors.Count); // derived type instance, $select=ActionName Employee employee = contextWrapper.Execute <Employee>(new Uri(this.ServiceUri + "Person(0)?$select=PersonId," + actionName, UriKind.Absolute)).Single(); Dictionary <string, string> expectedLinkValues = new Dictionary <string, string>() { { ActionOverloadingQueryTests.MetadataPrefix + actionName, "Person(0)/" + ActionOverloadingQueryTests.EmployeeTypeName + "/" + actionName }, }; IEnumerable <OperationDescriptor> employeeDescriptors = contextWrapper.GetEntityDescriptor(employee).OperationDescriptors; this.VerifyLinks(expectedLinkValues, employeeDescriptors); // derived type instance, $select=DerivedType/ActionName contextWrapper.Detach(employee); employee = contextWrapper.Execute <Employee>(new Uri(this.ServiceUri + "Person(0)?$select=PersonId," + ActionOverloadingQueryTests.EmployeeTypeName + "/" + actionName, UriKind.Absolute)).Single(); employeeDescriptors = contextWrapper.GetEntityDescriptor(employee).OperationDescriptors; this.VerifyLinks(expectedLinkValues, employeeDescriptors); // derived type instance, $select=Microsoft.Test.OData.Services.AstoriaDefaultService.* SpecialEmployee specialEmployee = contextWrapper.Execute <SpecialEmployee>(new Uri(this.ServiceUri + "Person(-7)?$select=PersonId," + "Microsoft.Test.OData.Services.AstoriaDefaultService.*", UriKind.Absolute)).Single(); expectedLinkValues = new Dictionary <string, string>() { { ActionOverloadingQueryTests.MetadataPrefix + actionName, "Person(-7)/" + ActionOverloadingQueryTests.SpecialEmployeeTypeName + "/" + actionName } }; IEnumerable <OperationDescriptor> specialEmployeeDescriptors = contextWrapper.GetEntityDescriptor(specialEmployee).OperationDescriptors; this.VerifyLinks(expectedLinkValues, specialEmployeeDescriptors); // derived type instance, $select=BaseType/ActionName contextWrapper.Detach(specialEmployee); specialEmployee = contextWrapper.Execute <SpecialEmployee>(new Uri(this.ServiceUri + "Person(-7)?$select=PersonId," + ActionOverloadingQueryTests.EmployeeTypeName + "/" + actionName, UriKind.Absolute)).Single(); specialEmployeeDescriptors = contextWrapper.GetEntityDescriptor(specialEmployee).OperationDescriptors; this.VerifyLinks(expectedLinkValues, specialEmployeeDescriptors); } }
/// <summary> /// Adds an operation descriptor to the list of operation descriptors. /// </summary> /// <param name="operationDescriptor">the operation descriptor to add.</param> internal void AddOperationDescriptor(OperationDescriptor operationDescriptor) { Debug.Assert(operationDescriptor != null, "operationDescriptor != null"); if (this.operationDescriptors == null) { this.operationDescriptors = new List <OperationDescriptor>(); } // The protocol allows multiple descriptors with the same rel, so we don't check for duplicate entries here. this.operationDescriptors.Add(operationDescriptor); }
public void InvokeFunctionBoundedToSingleton() { var employeeCount = TestClientContext.Execute <int>(new Uri(ServiceBaseUri.AbsoluteUri + "Company/Microsoft.Test.OData.Services.ODataWCFService.GetEmployeesCount()", UriKind.Absolute)).Single(); Assert.AreEqual(2, employeeCount); Company company = TestClientContext.Company.GetValue(); OperationDescriptor descriptor = TestClientContext.GetEntityDescriptor(company).OperationDescriptors.Single(e => e.Title == "Microsoft.Test.OData.Services.ODataWCFService.GetEmployeesCount"); employeeCount = TestClientContext.Execute <int>(descriptor.Target, "GET", true).Single(); Assert.AreEqual(2, employeeCount); }
private async Task WriteResponseStream(OperationDescriptor operationDescriptor, Stream stream, object content) { if (operationDescriptor.IsIterator) { await WriteResponseStreamWithBuffer(stream, content as IEnumerable); } else { var b = _serializer.Serialize(content); await stream.WriteAsync(b, 0, b.Length); } }
private object[] ReadParams(HttpContext context, OperationDescriptor descriptor) { byte[] parmasData; using (MemoryStream ms = new MemoryStream()) { context.Request.Body.CopyTo(ms); parmasData = ms.ToArray(); } var paramsHolder = _serializer.Deserialize(descriptor.ParamsSerializationType, parmasData); return(descriptor.UnboxParameterValues(paramsHolder)); }
public ICodeDescriptor Generate( IModelGeneratorContext context, ObjectType operationType, OperationDefinitionNode operation, ICodeDescriptor resultType) { var arguments = new List <Descriptors.IArgumentDescriptor>(); foreach (VariableDefinitionNode variableDefinition in operation.VariableDefinitions) { string typeName = variableDefinition.Type.NamedType().Name.Value; if (!context.Schema.TryGetType(typeName, out INamedType namedType)) { throw new InvalidOperationException( $"The variable type `{typeName}` is not supported by the schema."); } IType type = variableDefinition.Type.ToType(namedType); IInputClassDescriptor?inputClassDescriptor = null; if (namedType is InputObjectType inputObjectType) { inputClassDescriptor = GenerateInputObjectType(context, inputObjectType); } arguments.Add(new ArgumentDescriptor( variableDefinition.Variable.Name.Value, type, variableDefinition, inputClassDescriptor)); } string operationName = context.GetOrCreateName( operation, GetClassName(operation.Name !.Value) + "Operation"); var descriptor = new OperationDescriptor( operationName, context.Namespace, operationType, operation, arguments, context.Query, resultType); context.Register(descriptor); return(descriptor); }
string GetHttpMethodForOperation(OperationDescriptor operation) { if (operation.HttpOperationAttribute != null) { return(operation.HttpOperationAttribute.Method); } var match = Regex.Match(operation.Name, "^[A-Z][a-z]*"); if (match.Success) { return(match.Value.ToUpperInvariant()); } return(operation.Name.ToUpperInvariant()); }
static MainSession() { SampleFlagProperty = DataPropertyDescriptor <bool> .Register("SampleFlag", typeof(MainSession)); IsLoggedInProperty = DataPropertyDescriptor <bool> .Register("IsLoggedIn", typeof(MainSession)); SubSessionProperty = SessionPropertyDescriptor <SubSession> .Register("SubSession", typeof(MainSession)); LoginSessionProperty = SessionPropertyDescriptor <LoginSession> .Register("LoginSession", typeof(MainSession)); DoActionOperation = OperationDescriptor.Register("DoAction", typeof(MainSession)); DoOtherActionOperation = OperationDescriptor.Register("DoOtherAction", typeof(MainSession)); LogOutOperation = OperationDescriptor.Register("LogOut", typeof(MainSession)); OnStaticConstruction(); }
public void InvokeActionBoundedToSingleton() { Company company = TestClientContext.Company.GetValue(); TestClientContext.LoadProperty(company, "Revenue"); var newValue = TestClientContext.Execute <Int64>(new Uri(ServiceBaseUri.AbsoluteUri + "Company/Microsoft.Test.OData.Services.ODataWCFService.IncreaseRevenue"), "POST", true, new BodyOperationParameter("IncreaseValue", 20000)); Assert.AreEqual(newValue.Single(), company.Revenue + 20000); OperationDescriptor descriptor = TestClientContext.GetEntityDescriptor(company).OperationDescriptors.Single(e => e.Title == "Microsoft.Test.OData.Services.ODataWCFService.IncreaseRevenue"); newValue = TestClientContext.Execute <Int64>(descriptor.Target, "POST", new BodyOperationParameter("IncreaseValue", 40000)); Assert.AreEqual(newValue.Single(), company.Revenue + 60000); }
static LoginSession() { UserNameProperty = DataPropertyDescriptor <string> .Register("UserName", typeof(LoginSession)); PasswordProperty = DataPropertyDescriptor <string> .Register("Password", typeof(LoginSession)); NewUserNameProperty = DataPropertyDescriptor <string> .Register("NewUserName", typeof(LoginSession)); NewPassword1Property = DataPropertyDescriptor <string> .Register("NewPassword1", typeof(LoginSession)); NewPassword2Property = DataPropertyDescriptor <string> .Register("NewPassword2", typeof(LoginSession)); LoginOperation = OperationDescriptor.Register("Login", typeof(LoginSession)); RegisterOperation = OperationDescriptor.Register("Register", typeof(LoginSession)); OnStaticConstruction(); }
public void OverloadedActionsProjection() { for (int i = 1; i < 2; i++) { var contextWrapper = this.CreateWrappedContext(); if (i == 0) { //contextWrapper.Format.UseAtom(); } Product product = contextWrapper.Execute <Product>(new Uri(this.ServiceUri + "Product(-10)?$select=Microsoft.Test.OData.Services.AstoriaDefaultService.*", UriKind.Absolute)).Single(); OperationDescriptor productOperationDescriptor = contextWrapper.GetEntityDescriptor(product).OperationDescriptors.Single(); Assert.AreEqual(this.ServiceUri + ActionOverloadingQueryTests.MetadataPrefix + "RetrieveProduct", productOperationDescriptor.Metadata.AbsoluteUri, true); Assert.AreEqual(this.ServiceUri + "Product(-10)/Microsoft.Test.OData.Services.AstoriaDefaultService.RetrieveProduct", productOperationDescriptor.Target.AbsoluteUri, true); OrderLine orderLine = contextWrapper.Execute <OrderLine>(new Uri(this.ServiceUri + "OrderLine(OrderId=-10,ProductId=-10)?$select=*")).Single(); Assert.AreEqual(0, contextWrapper.GetEntityDescriptor(orderLine).OperationDescriptors.Count); } }
internal void OnAsyncRunningOpComplete(Task t) { Debug.Assert(_runningOp != null, "How did m_runningOp get cleared?"); Debug.Assert(t == _runningOp.Task, "Why is a different task completing?"); if (t.Exception != null) { if (t.Exception.InnerException != null) { _runningOp.ExceptionDispatchInfo = ExceptionDispatchInfo.Capture(t.Exception.InnerException); } else { _runningOp.ExceptionDispatchInfo = ExceptionDispatchInfo.Capture(t.Exception); } } _runningOp.MarkComplete(); _runningOp = null; _runningOpCompleteEvent.Set(); }
private bool TrySetOperationInternal(Delegate op) { lock (_eventLock) { if (_isClosed) throw new ObjectDisposedException("WorkerThread"); if (_runningOp == null) { _runningOpCompleteEvent.Reset(); OperationDescriptor runningOp = new OperationDescriptor(op); _runningOp = runningOp; _opSet.Set(); _runningOpCompleteEvent.WaitOne(); Debug.Assert(runningOp.IsComplete, "Why isn't the running op complete?"); if (runningOp.ExceptionDispatchInfo != null) { runningOp.ExceptionDispatchInfo.Throw(); } return true; } } return false; }
public SerializationTypeCreator(OperationDescriptor operationDescriptor) { _operationDescriptor = operationDescriptor; _typeName = $"{operationDescriptor.Service.Name}_{operationDescriptor.Name}"; }
// Thread routine for the poll loop. It handles calls coming in from the debug engine as well as polling for debug events. private void ThreadFunc() { while (!_isClosed) { // Wait for an operation to be set _opSet.WaitOne(); // Run until we go through a loop where there was nothing to do bool ranOperation; do { ranOperation = false; OperationDescriptor runningOp = _runningOp; if (runningOp != null && !runningOp.IsStarted) { runningOp.MarkStarted(); ranOperation = true; bool completeAsync = false; Operation syncOp = runningOp.Target as Operation; if (syncOp != null) { try { syncOp(); } catch (Exception opException) when(ExceptionHelper.BeforeCatch(opException, Logger, reportOnlyCorrupting: true)) { runningOp.ExceptionDispatchInfo = ExceptionDispatchInfo.Capture(opException); } } else { AsyncOperation asyncOp = (AsyncOperation)runningOp.Target; try { runningOp.Task = asyncOp(); } catch (Exception opException) when(ExceptionHelper.BeforeCatch(opException, Logger, reportOnlyCorrupting: true)) { runningOp.ExceptionDispatchInfo = ExceptionDispatchInfo.Capture(opException); } if (runningOp.Task != null) { runningOp.Task.ContinueWith(OnAsyncRunningOpComplete, TaskContinuationOptions.ExecuteSynchronously); completeAsync = true; } } if (!completeAsync) { runningOp.MarkComplete(); Debug.Assert(_runningOp == runningOp, "How did m_runningOp change?"); _runningOp = null; _runningOpCompleteEvent.Set(); } } Operation postedOperation = null; lock (_postedOperations) { if (_postedOperations.Count > 0) { postedOperation = _postedOperations.Dequeue(); } } if (postedOperation != null) { ranOperation = true; try { postedOperation(); } catch (Exception e) when(ExceptionHelper.BeforeCatch(e, Logger, reportOnlyCorrupting: false)) { if (PostedOperationErrorEvent != null) { PostedOperationErrorEvent(this, e); } } } }while (ranOperation); } }
public MyOperationDescriptor(OperationDescriptor od) { this.Title = od.Title; this.Metadata = od.Metadata.IsAbsoluteUri ? od.Metadata.AbsoluteUri : od.Metadata.OriginalString; this.Target = od.Target.AbsoluteUri; }
// Thread routine for the poll loop. It handles calls coming in from the debug engine as well as polling for debug events. private void ThreadFunc() { while (!_isClosed) { // Wait for an operation to be set _opSet.WaitOne(); // Run until we go through a loop where there was nothing to do bool ranOperation; do { ranOperation = false; OperationDescriptor runningOp = _runningOp; if (runningOp != null && !runningOp.IsStarted) { runningOp.MarkStarted(); ranOperation = true; bool completeAsync = false; Operation syncOp = runningOp.Target as Operation; if (syncOp != null) { try { syncOp(); } catch (Exception opException) when (ExceptionHelper.BeforeCatch(opException, Logger, reportOnlyCorrupting: true)) { runningOp.ExceptionDispatchInfo = ExceptionDispatchInfo.Capture(opException); } } else { AsyncOperation asyncOp = (AsyncOperation)runningOp.Target; try { runningOp.Task = asyncOp(); } catch (Exception opException) when (ExceptionHelper.BeforeCatch(opException, Logger, reportOnlyCorrupting: true)) { runningOp.ExceptionDispatchInfo = ExceptionDispatchInfo.Capture(opException); } if (runningOp.Task != null) { runningOp.Task.ContinueWith(OnAsyncRunningOpComplete, TaskContinuationOptions.ExecuteSynchronously); completeAsync = true; } } if (!completeAsync) { runningOp.MarkComplete(); Debug.Assert(_runningOp == runningOp, "How did m_runningOp change?"); _runningOp = null; _runningOpCompleteEvent.Set(); } } Operation postedOperation = null; lock (_postedOperations) { if (_postedOperations.Count > 0) { postedOperation = _postedOperations.Dequeue(); } } if (postedOperation != null) { ranOperation = true; try { postedOperation(); } catch (Exception e) when (ExceptionHelper.BeforeCatch(e, Logger, reportOnlyCorrupting: false)) { if (PostedOperationErrorEvent != null) { PostedOperationErrorEvent(this, e); } } } } while (ranOperation); } }
private bool TrySetOperationInternalWithProgress(AsyncProgressOperation op, string text, CancellationTokenSource canTokenSource) { var waitLoop = new HostWaitLoop(text); lock (_eventLock) { if (_isClosed) throw new ObjectDisposedException("WorkerThread"); if (_runningOp == null) { _runningOpCompleteEvent.Reset(); OperationDescriptor runningOp = new OperationDescriptor(new AsyncOperation(() => { return op(waitLoop); })); _runningOp = runningOp; _opSet.Set(); waitLoop.Wait(_runningOpCompleteEvent, canTokenSource); Debug.Assert(runningOp.IsComplete, "Why isn't the running op complete?"); if (runningOp.ExceptionDispatchInfo != null) { runningOp.ExceptionDispatchInfo.Throw(); } return true; } } return false; }