示例#1
0
        static void Interact(WorkflowApplication application)
        {
            IList <BookmarkInfo> bookmarks = application.GetBookmarks();

            while (true)
            {
                Console.Write("Bookmarks:");
                foreach (BookmarkInfo info in bookmarks)
                {
                    Console.Write(" '" + info.BookmarkName + "'");
                }
                Console.WriteLine();

                Console.WriteLine("Enter the name of the bookmark to resume");
                string bookmarkName = Console.ReadLine();

                if (bookmarkName != null && !bookmarkName.Equals(string.Empty))
                {
                    Console.WriteLine("Enter the payload for the bookmark '{0}'", bookmarkName);
                    string bookmarkPayload = Console.ReadLine();

                    BookmarkResumptionResult result = application.ResumeBookmark(bookmarkName, bookmarkPayload);
                    if (result == BookmarkResumptionResult.Success)
                    {
                        return;
                    }
                    else
                    {
                        Console.WriteLine("BookmarkResumptionResult: " + result);
                    }
                }
            }
        }
示例#2
0
        public Boolean Start(ILog data)
        {
            Variable <ILog> log = new Variable <ILog>("log", data);


            this.workflow = new Sequence
            {
                Activities =
                {
                    new Caller()
                    {
                        BookmarkName = "Caller"
                    },
                    new NewOpen()
                    {
                        BookmarkName = "NewOpen"
                    },
                }
            };

            WorkflowApplication wfApp = new WorkflowApplication(workflow);

            AutoResetEvent idleEvent = new AutoResetEvent(false);

            wfApp.Idle = (WorkflowApplicationIdleEventArgs e) => { idleEvent.Set(); };

            wfApp.Run();

            BookmarkResumptionResult result = wfApp.ResumeBookmark("NewOpen", data);

            idleEvent.WaitOne();

            return(result == BookmarkResumptionResult.Success);
        }
示例#3
0
            private bool ProcessResumption()
            {
                var stillSync = true;

                this.resumptionResult = this.instance.ResumeBookmarkCore(this.bookmark, this.value);

                if (this.resumptionResult == BookmarkResumptionResult.Success)
                {
                    if (this.instance.Controller.HasPendingTrackingRecords)
                    {
                        var result = this.instance.Controller.BeginFlushTrackingRecords(this.timeoutHelper.RemainingTime(), this.PrepareAsyncCompletion(trackingCompleteCallback), this);

                        if (result.CompletedSynchronously)
                        {
                            stillSync = OnTrackingComplete(result);
                        }
                        else
                        {
                            stillSync = false;
                        }
                    }
                }
                else if (this.resumptionResult == BookmarkResumptionResult.NotReady)
                {
                    this.NotifyOperationComplete();
                    this.currentOperation = new DeferredRequiresIdleOperation();
                }

                return(stillSync);
            }
示例#4
0
        private async Task <BookmarkResumptionResult> ResumeInstanceBookmarkAsync(Bookmark bookmark, object value, TimeSpan timeout)
        {
            await WaitIdleAsync(timeout);

            try
            {
                await PrepareAsync();

                BookmarkResumptionResult result = await instance.ScheduleBookmarkResumptionAsync(bookmark, value);

                if (result == BookmarkResumptionResult.Success)
                {
                    await instance.RunAsync();
                }
                else
                {
                    idle.Set();
                }

                return(result);
            }
            catch
            {
                // TODO shouldn't we only set idle, if RunAsync() wasn't successful and instance.WorkflowInstanceState != WorkflowInstanceState.Runnable ???
                idle.Set();
                throw;
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="BookmarkResumptionException"/> class. 
 /// </summary>
 /// <param name="bookmarkName">
 /// The bookmark Name. 
 /// </param>
 /// <param name="result">
 /// The result. 
 /// </param>
 /// <param name="value">The resumption value </param>
 /// <param name="innerException">
 /// The inner Exception. 
 /// </param>
 public BookmarkResumptionException(string bookmarkName, BookmarkResumptionResult result, object value = null, Exception innerException = null)
     : base(string.Format(SR.Unable_to_resume_bookmark_name, bookmarkName, result), innerException)
 {
     this.BookmarkName = bookmarkName;
     this.Result = result;
     Value = value;
 }
        private void ProcessBookmarkResumptionResult(Bookmark timerBookmark, BookmarkResumptionResult result)
        {
            switch (result)
            {
            case BookmarkResumptionResult.Success:
            case BookmarkResumptionResult.NotFound:
                lock (this.ThisLock)
                {
                    if (!this.isDisposed)
                    {
                        this.RegisteredTimers.RemoveTimer(timerBookmark);
                    }
                    return;
                }
                break;

            case BookmarkResumptionResult.NotReady:
                break;

            default:
                return;
            }
            lock (this.ThisLock)
            {
                this.RegisteredTimers.RetryTimer(timerBookmark);
            }
        }
        private void ProcessBookmarkResumptionResult(Bookmark timerBookmark, BookmarkResumptionResult result)
        {
            switch (result)
            {
            case BookmarkResumptionResult.NotFound:
            case BookmarkResumptionResult.Success:
                // The bookmark is removed maybe due to WF cancel, abort or the bookmark succeeds
                // no need to keep the timer around
                lock (this.ThisLock)
                {
                    if (!this.isDisposed)
                    {
                        this.RegisteredTimers.RemoveTimer(timerBookmark);
                    }
                }
                break;

            case BookmarkResumptionResult.NotReady:
                // The workflow maybe in one of these states: Completed, Aborted, Abandoned, unloading, Suspended
                // In the first 3 cases, we will let TimerExtension.CancelTimer take care of the cleanup.
                // In the 4th case, we want the timer to retry when it is loaded back, in all 4 cases we don't need to delete the timer
                // In the 5th case, we want the timer to retry until it succeeds.
                // Retry:
                lock (this.ThisLock)
                {
                    this.RegisteredTimers.RetryTimer(timerBookmark);
                }
                break;
            }
        }
        public async Task <BookmarkResumptionResult> ScheduleBookmarkResumptionAsync(Bookmark bookmark, object value)
        {
            BookmarkResumptionResult resumptionResult = Controller.ScheduleBookmarkResumption(bookmark, value);

            if (resumptionResult == BookmarkResumptionResult.Success)
            {
                await IfHasPendingThenFlushTrackingRecordsAsync();
            }
            return(resumptionResult);
        }
        // If the resumption didn't timed out nor aborted, but not found, it tries to return the previous response parameter if the operation was idempotent,
        // ie. throws OperationRepeatedException, or throws InvalidOperationException if the previous response is not known (didn't happen or not idempotent).
        private async Task <TResponseParameter> ResumeOperationBookmarkAsync <TResponseParameter>(string operationName, object requestResult, Type responseParameterType)
            where TResponseParameter : class
        {
            await WaitIdleAsync(Parameters.ResumeOperationTimeout);

            try
            {
                await PrepareAsync();

                if (completionState == null)
                {
                    TaskCompletionSource <TResponseParameter> taskCompletionSource = new TaskCompletionSource <TResponseParameter>();
                    BookmarkResumptionResult result = await instance.ScheduleOperationBookmarkResumptionAsync(operationName, new object[] { taskCompletionSource, requestResult });

                    WorkflowInstanceState workflowInstanceState = instance.WorkflowInstanceState;
                    if (result == BookmarkResumptionResult.Success)
                    {
                        try
                        {
                            activeTaskCompletionSources.Add(taskCompletionSource);
                            await instance.RunAsync();

                            return(await taskCompletionSource.Task);
                        }
                        finally
                        {
                            activeTaskCompletionSources.Remove(taskCompletionSource);
                        }
                    }
                    else
                    {
                        if (result == BookmarkResumptionResult.NotReady && workflowInstanceState != WorkflowInstanceState.Complete)
                        {
                            // Instance is created but the initialization RunAsync() hasn't been called, this is impossible.
                            throw new InvalidOperationException($"Instance state is '{workflowInstanceState}', instance is not ready to process operation '{operationName}'.");
                        }
                        else // NotFound or NotReady && Complete, though the later is also not possible at this point, completionState != null after prepare in that case
                        {
                            throw previousResponseParameterExtension.CreatePreviousResponseParameterException <TResponseParameter>(operationName, responseParameterType);
                        }
                    }
                }
                else
                {
                    throw previousResponseParameterExtension.CreatePreviousResponseParameterException <TResponseParameter>(operationName, responseParameterType);
                }
            }
            catch
            {
                // TODO shouldn't we only set idle, if RunAsync() wasn't successful and instance.WorkflowInstanceState != WorkflowInstanceState.Runnable ???
                idle.Set();
                throw;
            }
        }
        private static void OnResumeBookmarkComplete(IAsyncResult result)
        {
            if (result.CompletedSynchronously)
            {
                return;
            }

            BookmarkResumptionState state = (BookmarkResumptionState)result.AsyncState;

            BookmarkResumptionResult resumptionResult = state.Instance.EndResumeBookmark(result);

            state.TimerExtension.ProcessBookmarkResumptionResult(state.TimerBookmark, resumptionResult);
        }
示例#11
0
        void OnEndResumeBookmark(IAsyncResult ar)
        {
            object[]            asyncState = ar.AsyncState as object[];
            WorkflowApplication instance   = asyncState[0] as WorkflowApplication;
            string bookmarkName            = asyncState[1] as string;

            BookmarkResumptionResult result = instance.EndResumeBookmark(ar);

            if (result != BookmarkResumptionResult.Success)
            {
                //it is possible the bookmark has been removed by some other event in the workflow
                //but that event will update the host - no need to do it here
                this.hostView.OutputWriter.WriteLine("Could not resume bookmark: {0} on instance {1}", bookmarkName, instance.Id);
            }
        }
        public async Task <BookmarkResumptionResult> ScheduleReminderBookmarkResumptionAsync(string reminderName)
        {
            BookmarkResumptionResult result = BookmarkResumptionResult.Success;

            if (!durableReminderExtension.IsReactivationReminder(reminderName))
            {
                result = await ScheduleBookmarkResumptionAsync(durableReminderExtension.GetBookmark(reminderName), null);

                if (result != BookmarkResumptionResult.NotReady || WorkflowInstanceState == WorkflowInstanceState.Complete) // Success || NotFound || NotReady && Complete
                {
                    durableReminderExtension.UnregisterReminder(reminderName);
                }
            }
            return(result);
        }
示例#13
0
        public void ResumeWorkFlow(BusinessObject.DtoModels.Game game)
        {
            Exception exception = new Exception();

            Guid workflowInstanceID = game.InstanceId;

            SqlWorkflowInstanceStore store = new SqlWorkflowInstanceStore(databaseConnection);

            store.InstanceLockedExceptionAction = InstanceLockedExceptionAction.BasicRetry;
            store.HostLockRenewalPeriod         = TimeSpan.FromSeconds(2);


            InstanceHandle             instanceHandle = store.CreateInstanceHandle();
            CreateWorkflowOwnerCommand createOwnerCmd = new CreateWorkflowOwnerCommand();
            InstanceView view = store.Execute(instanceHandle, createOwnerCmd, TimeSpan.FromSeconds(10));

            store.DefaultInstanceOwner = view.InstanceOwner;

            WorkflowApplicationInstance instance = WorkflowApplication.GetInstance(workflowInstanceID, store);

            AutoResetEvent syncEvent = new AutoResetEvent(false);

            WorkflowApplication wfApplication = new WorkflowApplication(new FlowchartNumberGuessWorkflow(), instance.DefinitionIdentity);

            wfApplication.PersistableIdle      = (e) => PersistableIdleAction.Unload;
            wfApplication.Unloaded             = (e) => { syncEvent.Set(); };
            wfApplication.OnUnhandledException = (e) =>
            {
                exception = e.UnhandledException;
                syncEvent.Set();
                return(UnhandledExceptionAction.Cancel);
            };

            wfApplication.Load(instance);

            BookmarkResumptionResult result = wfApplication.ResumeBookmark("Decision", game);

            syncEvent.WaitOne();

            if (exception.Message != string.Empty && exception.StackTrace != null)
            {
                throw exception;
            }

            DeleteWorkflowOwnerCommand deleteOwnerCmd = new DeleteWorkflowOwnerCommand();

            store.Execute(instanceHandle, deleteOwnerCmd, TimeSpan.FromSeconds(10));
        }
        public void ResumeBookmarkWhileTerminating()
        {
            s_exceptionType     = typeof(TAC.ApplicationException);
            s_exceptionMsg      = "I am throwing this Exception";
            s_terminationReason = "Just cus!";

            TestParallel parallel = new TestParallel("ParallelTest")
            {
                Branches =
                {
                    new TestSequence("BlockingBranch")
                    {
                        Activities =
                        {
                            new TestWriteLine("BeforeBlocking")
                            {
                                Message     = "I should be Executed",
                                HintMessage = "I should be Executed"
                            },
                            new TestBlockingActivity("Blocking", "BlockBranch")
                            {
                                ExpectedOutcome = Outcome.Faulted
                            }
                        }
                    },
                    new TestTerminateWorkflow("TerminatingBranch")
                    {
                        ExceptionExpression = ((env) => new TAC.ApplicationException("I am throwing this Exception")),
                        Reason = s_terminationReason,
                    },
                },
            };

            using (TestWorkflowRuntime testWorkflowRuntime = TestRuntime.CreateTestWorkflowRuntime(parallel))
            {
                testWorkflowRuntime.OnWorkflowCompleted += new EventHandler <TestWorkflowCompletedEventArgs>(workflowInstance_Completed);
                testWorkflowRuntime.ExecuteWorkflow();

                WaitForTerminationHelper(testWorkflowRuntime);

                // Try resuming the bookmark
                BookmarkResumptionResult result = testWorkflowRuntime.ResumeBookMark("Blocking", null);
                if (result != BookmarkResumptionResult.NotFound)
                {
                    throw new TestCaseFailedException("Bookmark should be cancelled");
                }
            }
        }
示例#15
0
        private async Task ResumeReminderBookmarkAsync(string reminderName)
        {
            await WaitIdleAsync(Parameters.ResumeInfrastructureTimeout);

            try
            {
                await PrepareAsync();

                if (completionState == null)
                {
                    BookmarkResumptionResult result = await instance.ScheduleReminderBookmarkResumptionAsync(reminderName);

                    WorkflowInstanceState workflowInstanceState = instance.WorkflowInstanceState;
                    if (result == BookmarkResumptionResult.Success)
                    {
                        await instance.RunAsync();
                    }
                    else
                    {
                        if (result == BookmarkResumptionResult.NotReady && workflowInstanceState != WorkflowInstanceState.Complete)
                        {
                            // Instance is created but the initialization RunAsync() hasn't been called, this is impossible.
                            throw new InvalidOperationException($"Instance state is '{workflowInstanceState}', instance is not ready to process reminder '{reminderName}'.");
                        }
                        else // NotFound or NotReady && Complete, though the later is also not possible at this point, completionState != null after prepare in that case
                             // If we don't find a reminder, it's not an issue, maybe the grain/silo crashed after the reminder was created but before the workflow state was persisted,
                             // or the grain/silo crashed after persistence but before the reminder was unregistered,
                             // it will be unregistered on the next persistence event.
                             // See ReminderTable for the detailed description of the algorithm.
                        {
                            idle.Set();
                        }
                    }
                }
                else
                {
                    await grain.UnregisterReminderAsync(reminderName);

                    idle.Set();
                }
            }
            catch
            {
                // TODO shouldn't we only set idle, if RunAsync() wasn't successful and instance.WorkflowInstanceState != WorkflowInstanceState.Runnable ???
                idle.Set();
                throw;
            }
        }
 private static void OnResumeBookmarkComplete(IAsyncResult result)
 {
     if (!result.CompletedSynchronously)
     {
         BookmarkResumptionState asyncState = (BookmarkResumptionState)result.AsyncState;
         try
         {
             BookmarkResumptionResult result2 = asyncState.Instance.EndResumeBookmark(result);
             asyncState.TimerExtension.ProcessBookmarkResumptionResult(asyncState.TimerBookmark, result2);
         }
         catch (TimeoutException)
         {
             asyncState.TimerExtension.ProcessBookmarkResumptionResult(asyncState.TimerBookmark, BookmarkResumptionResult.NotReady);
         }
     }
 }
        /// <summary>
        /// 从书签恢复
        /// </summary>
        /// <param name="bookmarkName">书签名称</param>
        /// <param name="parameters">参数字典</param>
        /// <returns>恢复结果</returns>
        public void ResumeFromBookmark(string bookmarkName, IDictionary <string, object> parameters)
        {
            BookmarkResumptionResult result = this.WorkflowApplication.ResumeBookmark(bookmarkName, parameters);

            if (result == BookmarkResumptionResult.NotReady)
            {
                this.WorkflowApplication.Unload();

                throw new ArgumentOutOfRangeException(nameof(bookmarkName), $"工作流实例\"{this.WorkflowInstanceId}\"的书签\"{bookmarkName}\"未准备就绪,请稍后再试!");
            }
            if (result == BookmarkResumptionResult.NotFound)
            {
                this.WorkflowApplication.Unload();

                throw new ArgumentOutOfRangeException(nameof(bookmarkName), $"工作流实例\"{this.WorkflowInstanceId}\"不存在书签\"{bookmarkName}\"!");
            }
        }
示例#18
0
        private void CancelChildWorkItem(IList <Guid> parthToChild, NativeActivityContext context)
        {
            ICancellableWorkItemWithChildren cancellationRoot = RootWorkItem.Get(context).GoToChild(parthToChild)
                                                                as ICancellableWorkItemWithChildren;

            if (cancellationRoot != null)
            {
                BookmarkResumptionResult cancelationRequestResult = context.ResumeBookmark(
                    new Bookmark(WorkItemCancelationScope.CancelableWorkItemBookmarkName(cancellationRoot.Id)),
                    cancellationRoot);

                if (cancelationRequestResult != BookmarkResumptionResult.Success)
                {
                    WorkItemCancelationScope.MarkTasksAsCancelled(cancellationRoot, context, "Because cancellation request.");
                }
            }
        }
示例#19
0
        private async Task ResumeReminderBookmarkAsync(string reminderName)
        {
            BookmarkResumptionResult result = await ScheduleAndRunInstanceAsync(Parameters.ResumeInfrastructureTimeout,
                                                                                () => instance.ScheduleReminderBookmarkResumptionAsync(reminderName),
                                                                                (_result) => _result == BookmarkResumptionResult.Success);

            WorkflowInstanceState workflowInstanceState = instance.WorkflowInstanceState;

            if (result == BookmarkResumptionResult.NotReady && workflowInstanceState != WorkflowInstanceState.Complete)
            {
                // Instance is created but the initialization RunAsync() hasn't been called, this is impossible.
                throw new InvalidOperationException($"Instance state is '{workflowInstanceState}', instance is not ready to process reminder '{reminderName}'.");
            }
            //else // NotFound, Complete or Success
            // If we don't find a reminder, it's not an issue, maybe the grain/silo crashed after the reminder was created but before the workflow state was persisted,
            // or the grain/silo crashed after persistence but before the reminder was unregistered,
            // it will be unregistered on the next persistence event.
            // See ReminderTable for the detailed description of the algorithm.
        }
        private void OnTimerFired(object state)
        {
            Bookmark nextExpiredBookmark;

            lock (this.ThisLock)
            {
                nextExpiredBookmark = this.RegisteredTimers.GetNextExpiredBookmark();
                if ((nextExpiredBookmark == null) || (this.RegisteredTimers.GetNextDueTime() > DateTime.UtcNow))
                {
                    return;
                }
            }
            WorkflowInstanceProxy instance = this.instance;

            if (instance != null)
            {
                IAsyncResult result2 = null;
                bool         completedSynchronously = false;
                try
                {
                    result2 = instance.BeginResumeBookmark(nextExpiredBookmark, null, TimeSpan.FromSeconds(2.0), onResumeBookmarkComplete, new BookmarkResumptionState(nextExpiredBookmark, this, instance));
                    completedSynchronously = result2.CompletedSynchronously;
                }
                catch (TimeoutException)
                {
                    this.ProcessBookmarkResumptionResult(nextExpiredBookmark, BookmarkResumptionResult.NotReady);
                }
                if (completedSynchronously && (result2 != null))
                {
                    try
                    {
                        BookmarkResumptionResult result = instance.EndResumeBookmark(result2);
                        this.ProcessBookmarkResumptionResult(nextExpiredBookmark, result);
                    }
                    catch (TimeoutException)
                    {
                        this.ProcessBookmarkResumptionResult(nextExpiredBookmark, BookmarkResumptionResult.NotReady);
                    }
                }
            }
        }
示例#21
0
        public void CancelWorkItem(List <Guid> rootToCanceledChildItemPath)
        {
            WorkflowApplication wfInstance;

            lock (_sinkRoot)
            {
                _runningWorkflows.TryGetValue(rootToCanceledChildItemPath[0], out wfInstance);
            }

            if (wfInstance != null)
            {
                Console.Write("cancellation requested for " +
                              rootToCanceledChildItemPath[rootToCanceledChildItemPath.Count - 1]);

                string bookmarksBefore = String.Join(" , ", wfInstance.GetBookmarks().Select(bookmark => bookmark.BookmarkName).ToArray());
                BookmarkResumptionResult bookmarkResumptionResult =
                    wfInstance.ResumeBookmark(ProgressTrackingInitializer.CancellationBookmark,
                                              rootToCanceledChildItemPath);
                string bookmarksAfter = String.Join(" , ", wfInstance.GetBookmarks().Select(bookmark => bookmark.BookmarkName).ToArray());
            }
        }
示例#22
0
        // If the resumption didn't timed out nor aborted, but not found, it tries to return the previous response parameter if the operation was idempotent,
        // ie. throws RepeatedOperationException, or throws InvalidOperationException if the previous response is not known (didn't happen or not idempotent).
        private async Task ResumeOperationBookmarkAsync <TResponseParameter>(string operationName, TaskCompletionSource <TResponseParameter> taskCompletionSource, object requestResult, Type responseParameterType,
                                                                             Func <object, RepeatedOperationException> createRepeatedOperationException)
            where TResponseParameter : class
        {
            BookmarkResumptionResult result = await ScheduleAndRunInstanceAsync(Parameters.ResumeOperationTimeout,
                                                                                () => instance.ScheduleOperationBookmarkResumptionAsync(operationName, new object[] { taskCompletionSource, requestResult }),
                                                                                (_result) => _result == BookmarkResumptionResult.Success,
                                                                                taskCompletionSource);

            WorkflowInstanceState workflowInstanceState = instance.WorkflowInstanceState;

            if (result == BookmarkResumptionResult.NotFound ||
                result == BookmarkResumptionResult.NotReady && workflowInstanceState == WorkflowInstanceState.Complete)
            {
                previousResponseParameterExtension.ThrowPreviousResponseParameter(operationName, responseParameterType, createRepeatedOperationException);
            }
            else if (result == BookmarkResumptionResult.NotReady) // && !Complete
            // Instance is created but the initialization RunAsync() hasn't been called, this is impossible.
            {
                throw new InvalidOperationException($"Instance state is '{workflowInstanceState}', instance is not ready to process operation '{operationName}'.");
            }
            //else // Success
        }
            bool PerformResumption()
            {
                // We always have the lock when entering this method

                bool waitFinishedSynchronously;
                bool completeSelf = false;

                // For ProtocolBookmark without Out-Of-Order messaging support, we will throw and 
                // propagate Fault to client in case of invalid state (similar to management commands).
                // Otherwise, the result consistent with WorkflowApplication will be return and 
                // the caller (eg. delay extension or OOM) needs to handle them accordingly.
                if (this.isResumeProtocolBookmark && this.instance.BufferedReceiveManager == null)
                {
                    this.instance.ValidateStateForResumeProtocolBookmark();
                }
                else
                {
                    if (this.instance.AreBookmarksInvalid(out this.resumptionResult))
                    {
                        return TrackPerformResumption(true);
                    }
                }

                do
                {
                    waitFinishedSynchronously = false;

                    bool bufferedReceiveEnabled = this.isResumeProtocolBookmark && this.instance.BufferedReceiveManager != null;
                    this.resumptionResult = this.instance.ResumeProtocolBookmarkCore(this.bookmark, this.value, this.bookmarkScope, bufferedReceiveEnabled, ref this.waitHandle, ref this.ownsLock);
                    if (this.resumptionResult == BookmarkResumptionResult.NotReady && !bufferedReceiveEnabled)
                    {
                        if (nextIdleCallback == null)
                        {
                            nextIdleCallback = new Action<object, TimeoutException>(OnNextIdle);
                        }
                        
                        if (this.waitHandle.WaitAsync(nextIdleCallback, this, !this.isResumeProtocolBookmark ? this.timeoutHelper.RemainingTime() : this.nextIdleTimeoutHelper.RemainingTime()))
                        {
                            // We now have the lock
                            this.ownsLock = true;

                            // We should retry the resumption synchronously
                            waitFinishedSynchronously = true;
                        }
                        else
                        {
                            return false;
                        }
                    }
                    else
                    {
                        completeSelf = true;
                        break;
                    }

                }
                while (waitFinishedSynchronously);

                return TrackPerformResumption(completeSelf);
            }
        bool AreBookmarksInvalid(out BookmarkResumptionResult result)
        {
            if (this.hasRaisedCompleted)
            {
                result = BookmarkResumptionResult.NotFound;
                return true;
            }
            else if (this.state == State.Unloaded || this.state == State.Aborted || this.state == State.Suspended)
            {
                result = BookmarkResumptionResult.NotReady;
                return true;
            }

            result = BookmarkResumptionResult.Success;
            return false;
        }
示例#25
0
        public BookmarkResumptionResult TryGenerateWorkItem(ActivityExecutor executor, ref Bookmark bookmark, BookmarkScope scope, object value, System.Activities.ActivityInstance isolationInstance, bool nonScopedBookmarksExist, out ActivityExecutionWorkItem workItem)
        {
            BookmarkManager          manager = null;
            Bookmark                 bookmark3;
            BookmarkCallbackWrapper  wrapper2;
            BookmarkResumptionResult result3;

            workItem = null;
            BookmarkScope key = scope;

            if (scope.IsDefault)
            {
                key = this.defaultScope;
            }
            this.bookmarkManagers.TryGetValue(key, out manager);
            if (manager == null)
            {
                BookmarkResumptionResult notFound = BookmarkResumptionResult.NotFound;
                if (this.uninitializedScopes != null)
                {
                    for (int i = 0; i < this.uninitializedScopes.Count; i++)
                    {
                        Bookmark bookmark2;
                        BookmarkCallbackWrapper  wrapper;
                        BookmarkResumptionResult notReady;
                        BookmarkScope            scope3 = this.uninitializedScopes[i];
                        if (!this.bookmarkManagers[scope3].TryGetBookmarkFromInternalList(bookmark, out bookmark2, out wrapper))
                        {
                            notReady = BookmarkResumptionResult.NotFound;
                        }
                        else if (this.IsExclusiveScopeUnstable(bookmark2))
                        {
                            notReady = BookmarkResumptionResult.NotReady;
                        }
                        else
                        {
                            notReady = this.bookmarkManagers[scope3].TryGenerateWorkItem(executor, true, ref bookmark, value, isolationInstance, out workItem);
                        }
                        switch (notReady)
                        {
                        case BookmarkResumptionResult.Success:
                            this.InitializeBookmarkScopeWithoutKeyAssociation(scope3, scope.Id);
                            return(BookmarkResumptionResult.Success);

                        case BookmarkResumptionResult.NotReady:
                            notFound = BookmarkResumptionResult.NotReady;
                            break;

                        default:
                            if ((notFound == BookmarkResumptionResult.NotFound) && !this.IsStable(scope3, nonScopedBookmarksExist))
                            {
                                notFound = BookmarkResumptionResult.NotReady;
                            }
                            break;
                        }
                    }
                }
                return(notFound);
            }
            if (!manager.TryGetBookmarkFromInternalList(bookmark, out bookmark3, out wrapper2))
            {
                result3 = BookmarkResumptionResult.NotFound;
            }
            else if (this.IsExclusiveScopeUnstable(bookmark3))
            {
                result3 = BookmarkResumptionResult.NotReady;
            }
            else
            {
                result3 = manager.TryGenerateWorkItem(executor, true, ref bookmark, value, isolationInstance, out workItem);
            }
            if ((result3 == BookmarkResumptionResult.NotFound) && !this.IsStable(key, nonScopedBookmarksExist))
            {
                result3 = BookmarkResumptionResult.NotReady;
            }
            return(result3);
        }
示例#26
0
        static bool HandleEndResumeBookmark(IAsyncResult result)
        {
            WorkflowOperationContext thisPtr = (WorkflowOperationContext)result.AsyncState;

            bool completed     = false;
            bool shouldAbandon = true;

            try
            {
                BookmarkResumptionResult resumptionResult = thisPtr.workflowInstance.EndResumeProtocolBookmark(result);
                if (resumptionResult != BookmarkResumptionResult.Success)
                {
                    // Raise UnkownMessageReceivedEvent when we fail to resume bookmark
                    thisPtr.OperationContext.Host.RaiseUnknownMessageReceived(thisPtr.OperationContext.IncomingMessage);

                    // Only delay-retry this operation once (and only if retries are supported). Future calls will ensure the bookmark is set.
                    if (thisPtr.workflowInstance.BufferedReceiveManager != null)
                    {
                        bool bufferSuccess = thisPtr.workflowInstance.BufferedReceiveManager.BufferReceive(
                            thisPtr.OperationContext, thisPtr.receiveContext, thisPtr.bookmark.Name, BufferedReceiveState.WaitingOnBookmark, false);
                        if (bufferSuccess)
                        {
                            if (TD.BufferOutOfOrderMessageNoBookmarkIsEnabled())
                            {
                                TD.BufferOutOfOrderMessageNoBookmark(thisPtr.eventTraceActivity, thisPtr.workflowInstance.Id.ToString(), thisPtr.bookmark.Name);
                            }

                            shouldAbandon = false;
                        }
                    }

                    // The throw exception is intentional whether or not BufferedReceiveManager is set.
                    // This is to allow exception to bubble up the stack to WCF to cleanup various state (like Transaction).
                    // This is queue scenario and as far as the client is concerned, the client will not see any exception.
                    throw FxTrace.Exception.AsError(new FaultException(OperationExecutionFault.CreateOperationNotAvailableFault(thisPtr.workflowInstance.Id, thisPtr.bookmark.Name)));
                }

                lock (thisPtr.thisLock)
                {
                    if (thisPtr.CurrentState == State.ResultReceived)
                    {
                        thisPtr.CurrentState = State.Completed;
                        if (thisPtr.pendingException != null)
                        {
                            throw FxTrace.Exception.AsError(thisPtr.pendingException);
                        }
                        completed = true;
                    }
                    else
                    {
                        thisPtr.CurrentState = State.WaitForResult;
                        completed            = false;
                    }

                    // we are not really completed until the ReceiveContext finishes its work
                    if (completed)
                    {
                        completed = thisPtr.ProcessReceiveContext();
                    }

                    shouldAbandon = false;
                }
            }
            finally
            {
                if (shouldAbandon)
                {
                    BufferedReceiveManager.AbandonReceiveContext(thisPtr.receiveContext);
                }
                thisPtr.RemovePendingOperation();
            }

            return(completed);
        }
示例#27
0
        public void Resume(Guid instandId, string bookmarkName, object info)
        {
            this.WFApplication.Load(instandId);

            BookmarkResumptionResult result = this.WFApplication.ResumeBookmark(bookmarkName, info);
        }
示例#28
0
        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.");

            BookmarkManager manager = null;

            workItem = null;
            BookmarkScope lookupScope = scope;

            if (scope.IsDefault)
            {
                lookupScope = _defaultScope;
            }

            // We don't really care about the return value since we'll
            // use null to know we should check uninitialized sub instances
            _bookmarkManagers.TryGetValue(lookupScope, out 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 (_uninitializedScopes != null)
                {
                    for (int i = 0; i < _uninitializedScopes.Count; i++)
                    {
                        BookmarkScope uninitializedScope = _uninitializedScopes[i];

                        Fx.Assert(_bookmarkManagers.ContainsKey(uninitializedScope), "We must always have the uninitialized sub instances.");

                        Bookmark internalBookmark;
                        BookmarkCallbackWrapper  callbackWrapper;
                        BookmarkResumptionResult resumptionResult;
                        if (!_bookmarkManagers[uninitializedScope].TryGetBookmarkFromInternalList(bookmark, out internalBookmark, out callbackWrapper))
                        {
                            resumptionResult = BookmarkResumptionResult.NotFound;
                        }
                        else if (IsExclusiveScopeUnstable(internalBookmark))
                        {
                            resumptionResult = BookmarkResumptionResult.NotReady;
                        }
                        else
                        {
                            resumptionResult = _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;
                                }
                            }
                        }
                    }
                }

                return(finalResult);
            }
            else
            {
                Bookmark bookmarkFromList;
                BookmarkCallbackWrapper  callbackWrapper;
                BookmarkResumptionResult resumptionResult;
                if (!manager.TryGetBookmarkFromInternalList(bookmark, out bookmarkFromList, out callbackWrapper))
                {
                    resumptionResult = BookmarkResumptionResult.NotFound;
                }
                else
                {
                    if (IsExclusiveScopeUnstable(bookmarkFromList))
                    {
                        resumptionResult = BookmarkResumptionResult.NotReady;
                    }
                    else
                    {
                        resumptionResult = manager.TryGenerateWorkItem(executor, true, ref bookmark, value, isolationInstance, out workItem);
                    }
                }


                if (resumptionResult == BookmarkResumptionResult.NotFound)
                {
                    if (!IsStable(lookupScope, nonScopedBookmarksExist))
                    {
                        resumptionResult = BookmarkResumptionResult.NotReady;
                    }
                }

                return(resumptionResult);
            }
        }
示例#29
0
        public ActionResult ToNextState(ItServiceItem isi, Guid instanceId, string NextLink, string libid, string Opinion)  //审批者到下一环节,思路:保存当前流程的数据,恢复bookmark到下一环节,并保存下一环节流程信息
        {
            #region 判断是不是当前处理人
            WorkFlowItem    cwfi          = bdb.WorkFlowItems.Where(i => i.WfInstanceId == instanceId).FirstOrDefault();
            string          currentUserId = User.Identity.GetUserId();
            ApplicationUser user          = db.Users.Include(i => i.Roles).FirstOrDefault(i => i.Id == currentUserId);
            if (cwfi.WfCurrentUser.ToString().Trim() != user.UserName.ToString().Trim())
            {
                var json = new
                {
                    errorMsg = "你不是当前处理人"
                };

                return(Json(json, "text/html", JsonRequestBehavior.AllowGet));
            }
            #endregion
            string[]            strs       = NextLink.Trim().Split('(');
            AutoResetEvent      syncEvent  = new AutoResetEvent(false);
            int                 isComplete = 0;
            WorkflowApplication wfApp      = new WorkflowApplication(new ItService())
            {
                InstanceStore   = CreateInstanceStore(),
                PersistableIdle = delegate(WorkflowApplicationIdleEventArgs e)
                {
                    //var ex = e.GetInstanceExtensions<CustomTrackingParticipant>();
                    // Outputs = ex.First().Outputs.ToString();
                    return(PersistableIdleAction.Unload);
                },
                Completed = delegate(WorkflowApplicationCompletedEventArgs e)
                {
                    isComplete = 1;
                    syncEvent.Set();
                },
                Aborted = delegate(WorkflowApplicationAbortedEventArgs e)
                {
                },
                Unloaded = delegate(WorkflowApplicationEventArgs e)
                {
                    syncEvent.Set();
                },
                OnUnhandledException = delegate(WorkflowApplicationUnhandledExceptionEventArgs e)
                {
                    return(UnhandledExceptionAction.Terminate);
                },
                Idle = delegate(WorkflowApplicationIdleEventArgs e)
                {
                }
            };
            var StateTracker = new StateMachineStateTracker(wfApp.WorkflowDefinition); //当前状态追踪
            wfApp.Extensions.Add(StateTracker);
            wfApp.Extensions.Add(new StateTrackerPersistenceProvider(StateTracker));
            var cu = new CustomTrackingParticipant();         //获取Activity内部变量
            wfApp.Extensions.Add(cu);                         //获取Activity内部变量需要的追踪器
            //Guid instanceId = wfApp.Id;
            var trackerInstance = StateMachineStateTracker.LoadInstance(instanceId, wfApp.WorkflowDefinition, ConfigurationManager.ConnectionStrings["ApacheConnection"].ConnectionString);
            wfApp.Load(instanceId);
            BookmarkResumptionResult result = wfApp.ResumeBookmark(trackerInstance.CurrentState, strs[0]);
            //BookmarkResumptionResult result = wfApp.ResumeBookmark(trackerInstance.CurrentState, NextLink.Trim());   //恢复当前状态,并进入下一个bookmark,注意使用Trim,开始没使用,NextLInk无法取到,调试了大半夜
            syncEvent.WaitOne();

            string CurrentUser;
            string OpinionField = "";
            string CurrentState;
            string completeStr = "";

            if (isComplete == 0)
            {
                if (strs.Count() == 1)
                {
                    CurrentUser = cu.Outputs["CurrentUser"].ToString();
                }
                else
                {
                    CurrentUser = db.LibraryApprovers.ToList().First(p => (p.LibID == libid) && (p.ApproverName == strs[1].Replace(")", ""))).Approver;
                }
                OpinionField = cu.Outputs["OpinionField"].ToString();
                CurrentState = StateTracker.CurrentState;
            }
            else
            {
                CurrentUser  = "******";
                CurrentState = "已结束";
                completeStr  = "->结束";
            }
            //string currentUserId = User.Identity.GetUserId();
            //ApplicationUser user = db.Users.Include(i => i.Roles).FirstOrDefault(i => i.Id == currentUserId);    //获取当前用户TrueName,为增加流转信息提供数据
            WorkFlowItem  wfi  = bdb.WorkFlowItems.Where(i => i.WfInstanceId == instanceId).FirstOrDefault();   //获取当前流程信息
            ItServiceItem cisi = bdb.ItServiceItems.Where(i => i.ID == isi.ID).FirstOrDefault();                //获取当前业务数据的信息

            //业务数据更新开始
            cisi.Title          = isi.Title;
            cisi.applicant      = isi.applicant;
            cisi.applicant_dept = isi.applicant_dept;
            //cisi.description = isi.description;
            cisi.isitype     = isi.isitype;
            cisi.sub_isitype = isi.sub_isitype;
            cisi.end_isitype = isi.end_isitype;
            cisi.Object      = isi.Object;
            cisi.Topic       = isi.Topic;
            cisi.Purpose     = isi.Purpose;
            cisi.Status      = 1;
            if (NextLink == "驳回")
            {
                cisi.Status = 3;
            }
            if (isComplete == 1)
            {
                cisi.isiCompleteDate = DateTime.Now;
                if (NextLink == "撤销")
                {
                    cisi.Status = 4;
                }
                else
                {
                    cisi.Status = 2;
                }
            }

            #region 审批意见更新开始
            if (Opinion != null)
            {
                if (Convert.ToString(Opinion) != "")
                {
                    if (wfi.WfWriteField.Trim() == "FirstExamine")
                    {
                        cisi.FirstExamine = cisi.FirstExamine + "<br>" + Opinion + "     (意见填写人:" + user.TrueName + "    时间:" + DateTime.Now + ")";
                    }
                    if (wfi.WfWriteField.Trim() == "SecondExamine")
                    {
                        cisi.SecondExamine = cisi.SecondExamine + "<br>" + Opinion + "     (意见填写人:" + user.TrueName + "    时间:" + DateTime.Now + ")";
                    }
                    if (wfi.WfWriteField.Trim() == "LastExamine")
                    {
                        cisi.LastExamine = cisi.LastExamine + "<br>" + Opinion + "     (意见填写人:" + user.TrueName + "    时间:" + DateTime.Now + ")";
                    }
                }
            }
            #endregion


            if (wfi != null)
            {
                wfi.WfCurrentUser = CurrentUser;
                wfi.Wfstatus      = CurrentState;
                wfi.WfWriteField  = OpinionField;
                if (isComplete == 1)
                {
                    wfi.WfCompleteDate = DateTime.Now;
                }
                wfi.WfFlowChart = wfi.WfFlowChart + "->" + trackerInstance.CurrentState + "(" + user.TrueName + ")" + completeStr;          //增加流转信息
                try
                {
                    bdb.SaveChanges();
                    var json = new
                    {
                        okMsg = "提交成功"
                    };

                    return(Json(json, "text/html", JsonRequestBehavior.AllowGet));
                }
                catch (Exception e)
                {
                    var json = new
                    {
                        errorMsg = "提交失败"
                    };

                    return(Json(json, "text/html", JsonRequestBehavior.AllowGet));
                }
            }
            else
            {
                var json = new
                {
                    errorMsg = "流程不存在"
                };

                return(Json(json, "text/html", JsonRequestBehavior.AllowGet));
            }
        }
 void ProcessBookmarkResumptionResult(Bookmark timerBookmark, BookmarkResumptionResult result)
 {
     switch (result)
     {
         case BookmarkResumptionResult.NotFound:
         case BookmarkResumptionResult.Success:
             // The bookmark is removed maybe due to WF cancel, abort or the bookmark succeeds
             // no need to keep the timer around
             lock (this.ThisLock)
             {
                 if (!this.isDisposed)
                 {
                     this.RegisteredTimers.RemoveTimer(timerBookmark);
                 }
             }
             break;
         case BookmarkResumptionResult.NotReady:
             // The workflow maybe in one of these states: Completed, Aborted, Abandoned, unloading, Suspended
             // In the first 3 cases, we will let TimerExtension.CancelTimer take care of the cleanup.
             // In the 4th case, we want the timer to retry when it is loaded back, in all 4 cases we don't need to delete the timer 
             // In the 5th case, we want the timer to retry until it succeeds. 
             // Retry:
             lock (this.ThisLock)
             {
                 this.RegisteredTimers.RetryTimer(timerBookmark);
             }
             break;
     }
 }
 private bool PerformResumption()
 {
     bool flag;
     bool completeSelf = false;
     if (this.isResumeProtocolBookmark && (this.instance.BufferedReceiveManager == null))
     {
         this.instance.ValidateStateForResumeProtocolBookmark();
     }
     else if (this.instance.AreBookmarksInvalid(out this.resumptionResult))
     {
         return this.TrackPerformResumption(true);
     }
     do
     {
         flag = false;
         bool bufferedReceiveEnabled = this.isResumeProtocolBookmark && (this.instance.BufferedReceiveManager != null);
         this.resumptionResult = this.instance.ResumeProtocolBookmarkCore(this.bookmark, this.value, this.bookmarkScope, bufferedReceiveEnabled, ref this.waitHandle, ref this.ownsLock);
         if ((this.resumptionResult == BookmarkResumptionResult.NotReady) && !bufferedReceiveEnabled)
         {
             if (nextIdleCallback == null)
             {
                 nextIdleCallback = new Action<object, TimeoutException>(WorkflowServiceInstance.ResumeProtocolBookmarkAsyncResult.OnNextIdle);
             }
             if (!this.waitHandle.WaitAsync(nextIdleCallback, this, !this.isResumeProtocolBookmark ? this.timeoutHelper.RemainingTime() : this.nextIdleTimeoutHelper.RemainingTime()))
             {
                 return false;
             }
             this.ownsLock = true;
             flag = true;
         }
         else
         {
             completeSelf = true;
             break;
         }
     }
     while (flag);
     return this.TrackPerformResumption(completeSelf);
 }
示例#32
0
        public ActionResult DrafterToNextState(ItServiceItem isi, Guid instanceId, string NextLink, string libid)  //起草者到下一环节
        {
            string[] strs = NextLink.Trim().Split('(');

            AutoResetEvent syncEvent = new AutoResetEvent(false);

            WorkflowApplication wfApp = new WorkflowApplication(new ItService())
            {
                InstanceStore   = CreateInstanceStore(),
                PersistableIdle = delegate(WorkflowApplicationIdleEventArgs e)
                {
                    //var ex = e.GetInstanceExtensions<CustomTrackingParticipant>();
                    // Outputs = ex.First().Outputs.ToString();`
                    return(PersistableIdleAction.Unload);
                },
                Completed = delegate(WorkflowApplicationCompletedEventArgs e)
                {
                },
                Aborted = delegate(WorkflowApplicationAbortedEventArgs e)
                {
                },
                Unloaded = delegate(WorkflowApplicationEventArgs e)
                {
                    syncEvent.Set();
                },
                OnUnhandledException = delegate(WorkflowApplicationUnhandledExceptionEventArgs e)
                {
                    return(UnhandledExceptionAction.Terminate);
                },
                Idle = delegate(WorkflowApplicationIdleEventArgs e)
                {
                }
            };
            var StateTracker = new StateMachineStateTracker(wfApp.WorkflowDefinition); //当前状态追踪

            wfApp.Extensions.Add(StateTracker);
            wfApp.Extensions.Add(new StateTrackerPersistenceProvider(StateTracker));
            var cu = new CustomTrackingParticipant();         //获取Activity内部变量

            wfApp.Extensions.Add(cu);                         //获取Activity内部变量需要的追踪器
            //Guid instanceId = wfApp.Id;
            var trackerInstance = StateMachineStateTracker.LoadInstance(instanceId, wfApp.WorkflowDefinition, ConfigurationManager.ConnectionStrings["ApacheConnection"].ConnectionString);

            wfApp.Load(instanceId);
            //BookmarkResumptionResult result = wfApp.ResumeBookmark(trackerInstance.CurrentState, NextLink.Trim());
            BookmarkResumptionResult result = wfApp.ResumeBookmark(trackerInstance.CurrentState, strs[0]);

            syncEvent.WaitOne();
            //string CurrentUser = cu.Outputs["CurrentUser"].ToString();
            string CurrentUser = db.LibraryApprovers.ToList().First(p => (p.LibID == libid) && (p.ApproverName == strs[1].Replace(")", ""))).Approver;
            //string CurrentRole = cu.Outputs["CurrentRole"].ToString();
            string OpinionField = cu.Outputs["OpinionField"].ToString();
            string Drafter      = cu.Outputs["Drafter"].ToString();
            var    CurrentState = StateTracker.CurrentState;
            //var Pt = StateTracker.PossibleTransitions;
            ApplicationUser user = db.Users.Include(i => i.Roles).FirstOrDefault(i => i.UserName == Drafter);    //获取当前用户username

            isi.drafter       = Drafter;
            isi.isiCreateDate = DateTime.Now;
            isi.Status        = 1;
            bdb.ItServiceItems.Add(isi);      //添加业务数据
            try
            {
                bdb.SaveChanges();
            }
            catch
            {
                var json = new
                {
                    errorMsg = "添加业务数据出错"
                };

                return(Json(json, "text/html", JsonRequestBehavior.AllowGet));
            }
            WorkFlowItem wf = new WorkFlowItem();

            wf.WfInstanceId   = instanceId;
            wf.WfType         = "专病库IT服务申请";
            wf.WfCurrentUser  = CurrentUser;
            wf.WfDrafter      = Drafter;
            wf.WfWriteField   = OpinionField;
            wf.Wfstatus       = CurrentState;
            wf.WfBussinessUrl = "/ItService/OpenWorkFlow?id=" + instanceId;
            wf.WfCreateDate   = DateTime.Now;
            wf.WfBusinessId   = isi.ID; //添加业务数据关联
            wf.WfFlowChart    = trackerInstance.CurrentState + "(" + user.TrueName + ")";
            bdb.WorkFlowItems.Add(wf);
            bdb.SaveChanges();
            try
            {
                bdb.SaveChanges();
                var json = new
                {
                    okMsg = "流程保存成功"
                };

                return(Json(json, "text/html", JsonRequestBehavior.AllowGet));
            }
            catch
            {
                var json = new
                {
                    errorMsg = "流程保存出错"
                };

                return(Json(json, "text/html", JsonRequestBehavior.AllowGet));
            }
        }
        private void ProcessBookmarkResumptionResult(Bookmark timerBookmark, BookmarkResumptionResult result)
        {
            switch (result)
            {
                case BookmarkResumptionResult.Success:
                case BookmarkResumptionResult.NotFound:
                    lock (this.ThisLock)
                    {
                        if (!this.isDisposed)
                        {
                            this.RegisteredTimers.RemoveTimer(timerBookmark);
                        }
                        return;
                    }
                    break;

                case BookmarkResumptionResult.NotReady:
                    break;

                default:
                    return;
            }
            lock (this.ThisLock)
            {
                this.RegisteredTimers.RetryTimer(timerBookmark);
            }
        }