Workflow notes 3 -- BookMark and persistence, workflowbookmark
BookMark
In our daily workflow usage, the whole workflow is not directly completed in one breath. Generally, a process is sent to a node, and the operator of the process node is, the process may not be processed immediately. The process will continue only when the handler processes the process. The handler of different process nodes can process different process nodes.
As if we were reading a book, we needed bookmarks to mark it. Now I have seen somewhere, and the workflow is the same. I need to use bookmarks, to determine which process can be handled by different roles.
1. In the WindowsWorkFlowApp project, create a "code activity" BookMarkCodeActivity
Change the inheritance class to NativeActivity, and the parameter type of the Execute method to NativeActivityContext. The Code is as follows:
Public sealed class BookMarkCodeActivity: NativeActivity {// define a string type activity input parameter public InArgument <string> BookMarkName {get; set;} // defines an output parameter, used for process judgment, which is equivalent to simulating the user's operation to process the process node public OutArgument <int> Num {get; set;} // creates a BookMark, let the process stop protected override void Execute (NativeActivityContext context) {// 1. obtain the BookMark name string strBookMarkName = context. getValue (BookMarkName); // 2. create a BookMark context. CRES AteBookmark (strBookMarkName, new BookmarkCallback (PreExecuteWorkFlow, otherwise, an error is reported during subsequent running. // </summary> protected override bool CanInduceIdle {get {return true; // base. canInduceIdle ;}//< summary> /// this method must be executed before the next state is resumed. /// </Summary> /// <param name = "context"> </param> /// <param name = "bookmark"> bookmarks </param> // /<param name = "value"> passed value </param> public void PreExecuteWorkFlow (NativeActivityContext context, bookmark bookmark, object value) {context. setValue (Num, Convert. toInt32 (value ));}}
2. Generate the project WindowsWorkFlowApp
3. Double-click State1 to add the code activity to State1 and create the variable Vnum.
4. Create the input parameter InputBookMarkName
5. Modify the Form1 form
Modify the workflow startup code:
Extract the WorkflowApplication app to the class.
App = new WorkflowApplication (new Activity1 (), new Dictionary <string, object> () {"InputName", "Michael Jacob" },{ "InputBookMarkName", txtBookMarkName. text}); app. idle = delegate (WorkflowApplicationIdleEventArgs er) {Console. writeLine ("workflow {0} is idle. ", er. instanceId); syncEvent. set (); // wake up here. If you do not want to let it go, the interface will be stuck when a bookmarkdonet is created. };
Add code for the "continue execution" button
// Wake up the BookMark Execution Process private void btnContinue_Click (object sender, EventArgs e) {// The PreExecuteWorkFlow method is called and the txtNum value is passed to the app. resumeBookmark (txtBookMarkName. text, int. parse (txtNum. text ));}
6. Double-click T1 to modify and add conditions for judgment.
If the value of the VNum variable is 5, execute State2.
7. Add T3. When the VNum variable value is not equal to 5, return to State1.
Double-click T3 to add conditions
8. The running result is as follows:
Workflow persistence
1. Create a database to persistently Save the workflow instance. Create a database WorkFlowDB:
CREATE DATABASE [WorkFlowDB] CONTAINMENT = NONE ON PRIMARY ( NAME = N'WorkFlowDB', FILENAME = N'G:\DataBase\WorkFlowDB.mdf' , SIZE = 5120KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB ) LOG ON ( NAME = N'WorkFlowDB_log', FILENAME = N'G:\DataBase\WorkFlowDB_log.ldf' , SIZE = 2048KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)GO
2. Create a new table to store the instance data of the workflow. How can I create a new table?
Go to the % WINDIR % \ Microsoft. NET \ Framework \ v4.xxx \ SQL \ EN folder and find the script. Press Win + R to run % WINDIR % \ Microsoft. NET \ Framework
After finding the two SQL scripts, run the SqlWorkflowInstanceStoreSchema. SQL file in the database WorkFlowDB, and then run the SqlWorkflowInstanceStoreLogic. SQL file. After the execution is complete, the following table is created in the WorkFlowDB database.
The InstancesTable table is used to store workflow instances.
3. Add the following two assembly references to the WindowsWorkFlowApp project:
4. Modify the workflow startup code
Introduce namespace
using System.Activities.DurableInstancing;
Modify the btnStartWorkFlow_Click code:
SqlWorkflowInstanceStore store = new SqlWorkflowInstanceStore(@"Server=.\MSSQLSERVER2012;database=WorkFlowDB;uid=sa;pwd=yujie1127); app.InstanceStore = store;
Only the two lines of code are required to execute persistence. When the workflow is re-opened next time, I need to find the data of the workflow instance from the database. In order to make the demo simple, here, I will put the primary key of the workflow instance directly on the From form interface for display. in work, we usually use data tables to store the data information.
5. Modify the Form1 code and btnContinue_Click
Using System; using System. activities; using System. collections. generic; using System. threading; using System. windows. forms; using System. activities. durableInstancing; namespace WindowsWorkFlowApp {public partial class Form1: Form {public Form1 () {InitializeComponent ();} static readonly string ConnStr = @ "Server =. \ MSSQLSERVER2012; database = WorkFlowDB; uid = sa; pwd = yujie1127 "; // WorkflowApplication app; Au ToResetEvent syncEvent = new AutoResetEvent (false); private void btnStartWorkFlow_Click (object sender, EventArgs e) {WorkflowApplication app = new WorkflowApplication (new Activity1 (), new Dictionary <string, object> () {"InputName", "Michael Smith"}, {"InputBookMarkName", txtBookMarkName. text}); SqlWorkflowInstanceStore store = new SqlWorkflowInstanceStore (ConnStr); app. instanceStore = store; txtID. text = App. id. toString (); WorkFlowEvent (app, syncEvent); app. run (); syncEvent. waitOne ();} private static void WorkFlowEvent (WorkflowApplication app, AutoResetEvent syncEvent) {# region workflow lifecycle event app. unloaded = delegate (WorkflowApplicationEventArgs er) {Console. writeLine ("workflow {0} unload. ", er. instanceId) ;}; app. completed = delegate (WorkflowApplicationCompletedEventArgs er) {Console. writeLine ("workflow {0} completed.", Er. instanceId); syncEvent. set () ;}; app. aborted = delegate (WorkflowApplicationAbortedEventArgs er) {Console. writeLine ("workflow {0} ended. ", er. instanceId) ;}; app. idle = delegate (WorkflowApplicationIdleEventArgs er) {Console. writeLine ("workflow {0} is idle. ", er. instanceId); syncEvent. set (); // wake up here. If you do not want to let it go, the interface will be stuck when a bookmarkdonet is created. }; App. persistableIdle = delegate (WorkflowApplicationIdleEventArgs er) {Console. writeLine ("persistence"); return PersistableIdleAction. unload;}; app. onUnhandledException = delegate (WorkflowApplicationUnhandledExceptionEventArgs er) {Console. writeLine ("OnUnhandledException in Workflow {0} \ n {1}", er. instanceId, er. unhandledException. message); return UnhandledExceptionAction. terminate ;};# endregion} // wake up the BookMark Execution Process private void btnContinue_Click (object sender, EventArgs e) {# region old code // The PreExecuteWorkFlow method is called here, and pass the txtNum value to the past // app. resumeBookmark (txtBookMarkName. text, int. parse (txtNum. text); # endregion WorkflowApplication app = new WorkflowApplication (new Activity1 (); SqlWorkflowInstanceStore store = new SqlWorkflowInstanceStore (ConnStr); app. instanceStore = store; WorkFlowEvent (app, syncEvent); app. load (Guid. parse (txtID. text); // load the workflow instance // continue to execute the workflow instance app. resumeBookmark (txtBookMarkName. text, int. parse (txtNum. text ));}}}View Code
6. We can see that a workflow instance has been added to the data table.
7. Close the application and restart it.
Find this ID from the database and enter it.
We can see that the entire workflow is completed. In this case, we can see that the workflow instance data in the data table has been deleted.
Download source code: WorkflowConsoleApp3.zip