Esempio n. 1
0
 public void NotifyUnhandledException(Exception exception, ActivityInstance source)
 {
     Fx.Assert(this.activityExecutor != null, "ActivityExecutor null in NotifyUnhandledException.");
     this.activityExecutor.NotifyUnhandledException(exception, source);
 }
Esempio n. 2
0
 public void SchedulerIdle()
 {
     Fx.Assert(this.activityExecutor != null, "ActivityExecutor null in SchedulerIdle.");
     this.activityExecutor.OnSchedulerIdle();
 }
Esempio n. 3
0
 public void ThreadAcquired()
 {
     Fx.Assert(this.activityExecutor != null, "ActivityExecutor null in ThreadAcquired.");
     this.activityExecutor.OnSchedulerThreadAcquired();
 }
Esempio n. 4
0
 internal void Open(Scheduler oldScheduler)
 {
     Fx.Assert(this.synchronizationContext == null, "can only open when in the created state");
     this.synchronizationContext = SynchronizationContextHelper.CloneSynchronizationContext(oldScheduler.synchronizationContext);
 }
Esempio n. 5
0
        private static void OnScheduledWork(object state)
        {
            Scheduler thisPtr = (Scheduler)state;

            // We snapshot these values here so that we can
            // use them after calling OnSchedulerIdle.
            //bool isTracingEnabled = FxTrace.Trace.ShouldTraceToTraceSource(TraceEventLevel.Informational);
            Guid oldActivityId      = Guid.Empty;
            Guid workflowInstanceId = Guid.Empty;

            //if (isTracingEnabled)
            //{
            //    oldActivityId = DiagnosticTraceBase.ActivityId;
            //    workflowInstanceId = thisPtr.callbacks.WorkflowInstanceId;
            //    FxTrace.Trace.SetAndTraceTransfer(workflowInstanceId, true);

            //    if (thisPtr.resumeTraceRequired)
            //    {
            //        if (TD.WorkflowActivityResumeIsEnabled())
            //        {
            //            TD.WorkflowActivityResume(workflowInstanceId);
            //        }
            //    }
            //}

            thisPtr.callbacks.ThreadAcquired();

            RequestedAction nextAction   = continueAction;
            bool            idleOrPaused = false;

            while (object.ReferenceEquals(nextAction, continueAction))
            {
                if (thisPtr.IsIdle || thisPtr.isPausing)
                {
                    idleOrPaused = true;
                    break;
                }

                // cycle through (queue->thisPtr.firstWorkItem->currentWorkItem)
                WorkItem currentWorkItem = thisPtr.firstWorkItem;

                // promote an item out of our work queue if necessary
                if (thisPtr.workItemQueue != null && thisPtr.workItemQueue.Count > 0)
                {
                    thisPtr.firstWorkItem = thisPtr.workItemQueue.Dequeue();
                }
                else
                {
                    thisPtr.firstWorkItem = null;
                }

                if (TD.ExecuteWorkItemStartIsEnabled())
                {
                    TD.ExecuteWorkItemStart();
                }

                nextAction = thisPtr.callbacks.ExecuteWorkItem(currentWorkItem);

                if (TD.ExecuteWorkItemStopIsEnabled())
                {
                    TD.ExecuteWorkItemStop();
                }
            }

            bool notifiedCompletion = false;
            bool isInstanceComplete = false;

            if (idleOrPaused || object.ReferenceEquals(nextAction, abortAction))
            {
                thisPtr.isPausing = false;
                thisPtr.isRunning = false;

                thisPtr.NotifyWorkCompletion();
                notifiedCompletion = true;

                //if (isTracingEnabled)
                //{
                //    isInstanceComplete = thisPtr.callbacks.IsCompleted;
                //}

                // After calling SchedulerIdle we no longer have the lock.  That means
                // that any subsequent processing in this method won't have the single
                // threaded guarantee.
                thisPtr.callbacks.SchedulerIdle();
            }
            else if (!object.ReferenceEquals(nextAction, yieldSilentlyAction))
            {
                Fx.Assert(nextAction is NotifyUnhandledExceptionAction, "This is the only other option");

                NotifyUnhandledExceptionAction notifyAction = (NotifyUnhandledExceptionAction)nextAction;

                // We only set isRunning back to false so that the host doesn't
                // have to treat this like a pause notification.  As an example,
                // a host could turn around and call run again in response to
                // UnhandledException without having to go through its operation
                // dispatch loop first (or request pause again).  If we reset
                // isPausing here then any outstanding operations wouldn't get
                // signaled with that type of host.
                thisPtr.isRunning = false;

                thisPtr.NotifyWorkCompletion();
                notifiedCompletion = true;

                //if (isTracingEnabled)
                //{
                //    isInstanceComplete = thisPtr.callbacks.IsCompleted;
                //}

                thisPtr.callbacks.NotifyUnhandledException(notifyAction.Exception, notifyAction.Source);
            }

            //if (isTracingEnabled)
            //{
            //    if (notifiedCompletion)
            //    {
            //        if (isInstanceComplete)
            //        {
            //            if (TD.WorkflowActivityStopIsEnabled())
            //            {
            //                TD.WorkflowActivityStop(workflowInstanceId);
            //            }
            //        }
            //        else
            //        {
            //            if (TD.WorkflowActivitySuspendIsEnabled())
            //            {
            //                TD.WorkflowActivitySuspend(workflowInstanceId);
            //            }
            //        }
            //    }

            //    DiagnosticTraceBase.ActivityId = oldActivityId;
            //}
        }
Esempio n. 6
0
 public void OnDeserialized(Callbacks callbacks)
 {
     Initialize(callbacks);
     Fx.Assert(this.firstWorkItem != null || this.workItemQueue == null, "cannot have items in the queue unless we also have a firstWorkItem set");
 }
Esempio n. 7
0
        // This method should only be called when we relinquished the thread but did not
        // complete the operation (silent yield is the current example)
        public void InternalResume(RequestedAction action)
        {
            Fx.Assert(this.isRunning, "We should still be processing work - we just don't have a thread");

            bool isTracingEnabled   = FxTrace.ShouldTraceInformation;
            bool notifiedCompletion = false;
            bool isInstanceComplete = false;

            if (this.callbacks.IsAbortPending)
            {
                this.isPausing = false;
                this.isRunning = false;

                this.NotifyWorkCompletion();
                notifiedCompletion = true;

                if (isTracingEnabled)
                {
                    isInstanceComplete = this.callbacks.IsCompleted;
                }

                // After calling SchedulerIdle we no longer have the lock.  That means
                // that any subsequent processing in this method won't have the single
                // threaded guarantee.
                this.callbacks.SchedulerIdle();
            }
            else if (object.ReferenceEquals(action, continueAction))
            {
                ScheduleWork(false);
            }
            else
            {
                Fx.Assert(action is NotifyUnhandledExceptionAction, "This is the only other choice because we should never have YieldSilently here");

                NotifyUnhandledExceptionAction notifyAction = (NotifyUnhandledExceptionAction)action;

                // We only set isRunning back to false so that the host doesn't
                // have to treat this like a pause notification.  As an example,
                // a host could turn around and call run again in response to
                // UnhandledException without having to go through its operation
                // dispatch loop first (or request pause again).  If we reset
                // isPausing here then any outstanding operations wouldn't get
                // signaled with that type of host.
                this.isRunning = false;

                this.NotifyWorkCompletion();
                notifiedCompletion = true;

                if (isTracingEnabled)
                {
                    isInstanceComplete = this.callbacks.IsCompleted;
                }

                this.callbacks.NotifyUnhandledException(notifyAction.Exception, notifyAction.Source);
            }

            if (isTracingEnabled)
            {
                if (notifiedCompletion)
                {
                    Guid oldActivityId = Guid.Empty;
                    bool resetId       = false;

                    if (isInstanceComplete)
                    {
                        if (TD.WorkflowActivityStopIsEnabled())
                        {
                            oldActivityId = WfEventSource.CurrentThreadActivityId;
                            WfEventSource.SetCurrentThreadActivityId(this.callbacks.WorkflowInstanceId);
                            resetId = true;

                            TD.WorkflowActivityStop(this.callbacks.WorkflowInstanceId);
                        }
                    }
                    else
                    {
                        if (TD.WorkflowActivitySuspendIsEnabled())
                        {
                            oldActivityId = WfEventSource.CurrentThreadActivityId;
                            WfEventSource.SetCurrentThreadActivityId(this.callbacks.WorkflowInstanceId);
                            resetId = true;

                            TD.WorkflowActivitySuspend(this.callbacks.WorkflowInstanceId);
                        }
                    }

                    if (resetId)
                    {
                        WfEventSource.SetCurrentThreadActivityId(oldActivityId);
                    }
                }
            }
        }
Esempio n. 8
0
        protected void Complete(bool completedSynchronously)
        {
            if (_isCompleted)
            {
                throw Fx.Exception.AsError(new InvalidOperationException(SR.AsyncResultCompletedTwice(GetType())));
            }

            //#if DEBUG
            //            this.marker.AsyncResult = null;
            //            this.marker = null;
            //            if (!Fx.FastDebug && completeStack == null)
            //            {
            //                completeStack = new StackTrace();
            //            }
            //#endif

            _completedSynchronously = completedSynchronously;
            if (OnCompleting != null)
            {
                // Allow exception replacement, like a catch/throw pattern.
                try
                {
                    OnCompleting(this, _exception);
                }
                catch (Exception exception)
                {
                    if (Fx.IsFatal(exception))
                    {
                        throw;
                    }
                    _exception = exception;
                }
            }

            if (completedSynchronously)
            {
                // If we completedSynchronously, then there's no chance that the manualResetEvent was created so
                // we don't need to worry about a race condition
                Fx.Assert(_manualResetEvent == null, "No ManualResetEvent should be created for a synchronous AsyncResult.");
                _isCompleted = true;
            }
            else
            {
                lock (ThisLock)
                {
                    _isCompleted = true;
                    if (_manualResetEvent != null)
                    {
                        _manualResetEvent.Set();
                    }
                }
            }

            if (_callback != null)
            {
                try
                {
                    if (VirtualCallback != null)
                    {
                        VirtualCallback(_callback, this);
                    }
                    else
                    {
                        _callback(this);
                    }
                }
#pragma warning disable 1634
#pragma warning suppress 56500 // transferring exception to another thread
                catch (Exception e)
                {
                    if (Fx.IsFatal(e))
                    {
                        throw;
                    }

                    throw Fx.Exception.AsError(new CallbackException(SR.AsyncCallbackThrewException, e));
                }
#pragma warning restore 1634
            }
        }
Esempio n. 9
0
 private void ScheduleCallback(Action <object> callback)
 {
     Fx.Assert(callback != null, "Cannot schedule a null callback");
     Task.Factory.StartNew(callback, this, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
 }
        public BookmarkResumptionResult TryGenerateWorkItem(ActivityExecutor executor, ref Bookmark bookmark, BookmarkScope scope, object value, ActivityInstance isolationInstance, bool nonScopedBookmarksExist, out ActivityExecutionWorkItem workItem)
        {
            Fx.Assert(scope != null, "We should never have a null sub instance.");

            workItem = null;
            BookmarkScope lookupScope = scope;

            if (scope.IsDefault)
            {
                lookupScope = this.defaultScope;
            }

            // We don't really care about the return value since we'll
            // use null to know we should check uninitialized sub instances
            this.bookmarkManagers.TryGetValue(lookupScope, out BookmarkManager manager);

            if (manager == null)
            {
                Fx.Assert(lookupScope != null, "The sub instance should not be default if we are here.");

                BookmarkResumptionResult finalResult = BookmarkResumptionResult.NotFound;

                // Check the uninitialized sub instances for a matching bookmark
                if (this.uninitializedScopes != null)
                {
                    for (int i = 0; i < this.uninitializedScopes.Count; i++)
                    {
                        BookmarkScope uninitializedScope = this.uninitializedScopes[i];

                        Fx.Assert(this.bookmarkManagers.ContainsKey(uninitializedScope), "We must always have the uninitialized sub instances.");
                        BookmarkResumptionResult resumptionResult;
                        if (!this.bookmarkManagers[uninitializedScope].TryGetBookmarkFromInternalList(bookmark, out Bookmark internalBookmark, out BookmarkCallbackWrapper callbackWrapper))
                        {
                            resumptionResult = BookmarkResumptionResult.NotFound;
                        }
                        else if (IsExclusiveScopeUnstable(internalBookmark))
                        {
                            resumptionResult = BookmarkResumptionResult.NotReady;
                        }
                        else
                        {
                            resumptionResult = this.bookmarkManagers[uninitializedScope].TryGenerateWorkItem(executor, true, ref bookmark, value, isolationInstance, out workItem);
                        }

                        if (resumptionResult == BookmarkResumptionResult.Success)
                        {
                            // We are using InitializeBookmarkScopeWithoutKeyAssociation because we know this is a new uninitialized scope and
                            // the key we would associate is already associated. And if we did the association here, the subsequent call to
                            // FlushBookmarkScopeKeys would try to flush it out, but it won't have the transaction correct so will hang waiting for
                            // the transaction that has the PersistenceContext locked to complete. But it won't complete successfully until
                            // we finish processing here.
                            InitializeBookmarkScopeWithoutKeyAssociation(uninitializedScope, scope.Id);

                            // We've found what we were looking for
                            return(BookmarkResumptionResult.Success);
                        }
                        else if (resumptionResult == BookmarkResumptionResult.NotReady)
                        {
                            // This uninitialized sub-instance has a matching bookmark but
                            // it can't currently be resumed.  We won't return BookmarkNotFound
                            // because of this.
                            finalResult = BookmarkResumptionResult.NotReady;
                        }
                        else
                        {
                            if (finalResult == BookmarkResumptionResult.NotFound)
                            {
                                // If we still are planning on returning failure then
                                // we'll incur the cost of seeing if this scope is
                                // stable or not.

                                if (!IsStable(uninitializedScope, nonScopedBookmarksExist))
                                {
                                    // There exists an uninitialized scope which is unstable.
                                    // At the very least this means we'll return NotReady since
                                    // this uninitialized scope might eventually contain this
                                    // bookmark.
                                    finalResult = BookmarkResumptionResult.NotReady;
                                }
                            }
                        }
                    }
                }
Esempio n. 11
0
 // this isn't just public for performance reasons. We avoid the virtual call
 // by going through Dispose()
 protected virtual void ReleaseToPool(ActivityExecutor executor)
 {
     Fx.Assert("This should never be called ... only overridden versions should get called.");
 }
Esempio n. 12
0
            public IOAsyncResult(PersistencePipeline pipeline, bool isLoad, TimeSpan timeout, AsyncCallback callback, object state)
                : base(callback, state)
            {
                _pipeline         = pipeline;
                _isLoad           = isLoad;
                _pendingModules   = _pipeline._modules.Where(value => value.IsIOParticipant).ToArray();
                _remainingModules = _pendingModules.Length;

                bool completeSelf = false;

                if (_pendingModules.Length == 0)
                {
                    completeSelf = true;
                }
                else
                {
                    for (int i = 0; i < _pendingModules.Length; i++)
                    {
                        Fx.Assert(!completeSelf, "Shouldn't have been completed yet.");

                        IPersistencePipelineModule module = _pendingModules[i];
                        IAsyncResult result = null;
                        try
                        {
                            if (_isLoad)
                            {
                                result = module.BeginOnLoad(_pipeline._readWriteView, timeout, Fx.ThunkCallback(new AsyncCallback(OnIOComplete)), i);
                            }
                            else
                            {
                                result = module.BeginOnSave(_pipeline._readWriteView, _pipeline._writeOnlyView, timeout, Fx.ThunkCallback(new AsyncCallback(OnIOComplete)), i);
                            }
                        }
                        catch (Exception exception)
                        {
                            if (Fx.IsFatal(exception))
                            {
                                throw;
                            }

                            _pendingModules[i] = null;
                            ProcessException(exception);
                        }
                        if (result == null)
                        {
                            if (CompleteOne())
                            {
                                completeSelf = true;
                            }
                        }
                        else if (result.CompletedSynchronously)
                        {
                            _pendingModules[i] = null;
                            if (IOComplete(result, module))
                            {
                                completeSelf = true;
                            }
                        }
                    }
                }

                if (completeSelf)
                {
                    Complete(true, _exception);
                }
            }
Esempio n. 13
0
        public override bool Execute(ActivityExecutor executor, BookmarkManager bookmarkManager)
        {
            Fx.Assert("Empty work items should never been executed.");

            return(true);
        }
Esempio n. 14
0
 public FatalException(string message, Exception innerException) : base(message, innerException)
 {
     // This can't throw something like ArgumentException because that would be worse than
     // throwing the fatal exception that was requested.
     Fx.Assert(innerException == null || !Fx.IsFatal(innerException), "FatalException can't be used to wrap fatal exceptions.");
 }