public void RegisterTask_AsynchronousCompletion_SwallowsExceptionsThrownByEndDelegate()
        {
            // Arrange
            SimpleSynchronizationContext syncContext = new SimpleSynchronizationContext();
            AsyncManager asyncManager = new AsyncManager(syncContext);
            bool endDelegateWasCalled = false;

            ManualResetEvent waitHandle = new ManualResetEvent(false /* initialState */);

            Func<AsyncCallback, IAsyncResult> beginDelegate = callback =>
            {
                MockAsyncResult asyncResult = new MockAsyncResult(false /* completedSynchronously */);
                ThreadPool.QueueUserWorkItem(_ =>
                {
                    callback(asyncResult);
                    waitHandle.Set();
                });
                return asyncResult;
            };
            Action<IAsyncResult> endDelegate = delegate
            {
                endDelegateWasCalled = true;
                throw new Exception("This is a sample exception.");
            };

            // Act
            asyncManager.RegisterTask(beginDelegate, endDelegate);
            waitHandle.WaitOne();

            // Assert
            Assert.True(endDelegateWasCalled);
            Assert.Equal(0, asyncManager.OutstandingOperations.Count);
        }
 private static void ProcessMessage(Message msg, AsyncManager asyncMgr)
 {
     switch (msg.Type)
     {
         case MessageTypes.Results:
             ProcessResults(msg, asyncMgr);
             break;
     }
     asyncMgr.OutstandingOperations.Decrement();
 }
        public static void Connect(Guid connectionId, AsyncManager asyncManager)
        {
            Complete(connectionId, null);

            lock (((IDictionary)Subscribers).SyncRoot)
            lock (((IDictionary)Connections).SyncRoot)
            {
                var timer = new Timer(TimeSpan.FromSeconds(10).TotalMilliseconds) { AutoReset = false };
                timer.Elapsed += (sender, args) => Complete(connectionId, null);
                Connections.Add(connectionId, new Connection(connectionId, asyncManager, timer));
                asyncManager.OutstandingOperations.Increment();
                timer.Start();
            }
        }
        public void RegisterTask_ResetsOutstandingOperationCountIfBeginMethodThrows()
        {
            // Arrange
            SimpleSynchronizationContext syncContext = new SimpleSynchronizationContext();
            AsyncManager asyncManager = new AsyncManager(syncContext);

            Func<AsyncCallback, IAsyncResult> beginDelegate = cb => { throw new InvalidOperationException("BeginDelegate throws."); };
            Action<IAsyncResult> endDelegate = ar => { Assert.True(false, "This should never be called."); };

            // Act & assert
            Assert.Throws<InvalidOperationException>(
                delegate { asyncManager.RegisterTask(beginDelegate, endDelegate); }, "BeginDelegate throws.");

            Assert.Equal(0, asyncManager.OutstandingOperations.Count);
        }
Exemple #5
0
        public override IAsyncResult BeginExecute(ControllerContext controllerContext, IDictionary <string, object> parameters, AsyncCallback callback, object state)
        {
            if (controllerContext == null)
            {
                throw new ArgumentNullException("controllerContext");
            }
            if (parameters == null)
            {
                throw new ArgumentNullException("parameters");
            }

            AsyncManager asyncManager = GetAsyncManager(controllerContext.Controller);

            BeginInvokeDelegate beginDelegate = delegate(AsyncCallback asyncCallback, object asyncState)
            {
                // call the XxxAsync() method
                ParameterInfo[] parameterInfos     = AsyncMethodInfo.GetParameters();
                var             rawParameterValues = from parameterInfo in parameterInfos
                                                     select ExtractParameterFromDictionary(parameterInfo, parameters, AsyncMethodInfo);

                object[] parametersArray = rawParameterValues.ToArray();

                TriggerListener   listener    = new TriggerListener();
                SimpleAsyncResult asyncResult = new SimpleAsyncResult(asyncState);

                // hook the Finished event to notify us upon completion
                Trigger finishTrigger = listener.CreateTrigger();
                asyncManager.Finished += delegate
                {
                    finishTrigger.Fire();
                };
                asyncManager.OutstandingOperations.Increment();

                // to simplify the logic, force the rest of the pipeline to execute in an asynchronous callback
                listener.SetContinuation(() => ThreadPool.QueueUserWorkItem(_ => asyncResult.MarkCompleted(false /* completedSynchronously */, asyncCallback)));

                // the inner operation might complete synchronously, so all setup work has to be done before this point
                ActionMethodDispatcher dispatcher = DispatcherCache.GetDispatcher(AsyncMethodInfo);
                dispatcher.Execute(controllerContext.Controller, parametersArray); // ignore return value from this method

                // now that the XxxAsync() method has completed, kick off any pending operations
                asyncManager.OutstandingOperations.Decrement();
                listener.Activate();
                return(asyncResult);
            };

            EndInvokeDelegate <object> endDelegate = delegate(IAsyncResult asyncResult)
            {
                // call the XxxCompleted() method
                ParameterInfo[] completionParametersInfos    = CompletedMethodInfo.GetParameters();
                var             rawCompletionParameterValues = from parameterInfo in completionParametersInfos
                                                               select ExtractParameterOrDefaultFromDictionary(parameterInfo, asyncManager.Parameters);

                object[] completionParametersArray = rawCompletionParameterValues.ToArray();

                ActionMethodDispatcher dispatcher = DispatcherCache.GetDispatcher(CompletedMethodInfo);
                object actionReturnValue          = dispatcher.Execute(controllerContext.Controller, completionParametersArray);
                return(actionReturnValue);
            };

            return(AsyncResultWrapper.Begin(callback, state, beginDelegate, endDelegate, _executeTag, asyncManager.Timeout));
        }
        public void RegisterTask_SynchronousCompletion()
        {
            // Arrange
            SimpleSynchronizationContext syncContext = new SimpleSynchronizationContext();
            AsyncManager asyncManager = new AsyncManager(syncContext);
            bool endDelegateWasCalled = false;

            Func<AsyncCallback, IAsyncResult> beginDelegate = callback =>
            {
                Assert.Equal(1, asyncManager.OutstandingOperations.Count);
                MockAsyncResult asyncResult = new MockAsyncResult(true /* completedSynchronously */);
                callback(asyncResult);
                return asyncResult;
            };
            Action<IAsyncResult> endDelegate = delegate { endDelegateWasCalled = true; };

            // Act
            asyncManager.RegisterTask(beginDelegate, endDelegate);

            // Assert
            Assert.True(endDelegateWasCalled);
            Assert.False(syncContext.SendWasCalled);
            Assert.Equal(0, asyncManager.OutstandingOperations.Count);
        }
 public Connection(Guid id, AsyncManager manager, Timer timer)
 {
     Id = id;
     Manager = manager;
     Timer = timer;
 }
 private static void ProcessResults(Message msg, AsyncManager asyncMgr)
 {
     var results = LogQueryResults.DeserializeLog(msg.Data);
     asyncMgr.Parameters["details"] = results.LogIDs;
 }
 public MovieInfoAsync(AsyncManager manager)
 {
     _manager = manager;
 }