Search

Search:

Namespace:

Search Result
.
See
.

To ensure consistency between the WorkflowInstance and the database being updated the TransactionScopeActivity is adorned with the PersistOnCloseAttribute. When the TransactionScopeActivity is used the WorkflowRuntime must be configured with a WorkflowPersistenceService. This could be the build in SqlWorkflowPersistenceService or another custom WorkflowPersistenceService.

.

However there is a catch. Suppose the external service isn't passively waiting for an external event but must do so in a more active mode. An example of this is a service waiting for a particular file to be recreated. In this case the service needs to be aware of the file we are waiting for even after a restart of the workflow runtime. When the workflow starts and uses a SqlWorkflowPersistenceService each workflow waiting for a DelayActivity is actually reloaded if the delay timer has expired. When this happens an OnActivityExecutionContextLoad() function is called on the activity waiting. This activity can now signal the external service that it is waiting for the file. Adding a dummy timer subscription isn't all that hard.

.

This code will prevent the requirements for an extra persistence service for use with the runtime service waiting for the file. Keep in mind though that this behavior depends on the internal, and undocumented, behavior of the DelayActivity and the SqlWorkflowPersistenceService so it could well change in the future.

.
Summary
A custom persistence service is a persistence service written by a third party that inherits from WorkflowPersistenceService and provides persistence services in however manner the developer chooses, its could be a database or file based persistence. For a sample about writing your own custom persistence service refer to the "Custom Persistence Service Sample" in the WF SDK.
.

Another possible reason is that the workflow you are sending a message to is already terminated. This might happen if your code is responding to an event that has already timed out allowing the workflow to terminate. The error is misleading in this case because the WorkflowRuntime doesn't know that the workflow has finished and tries to load it from the, in this case, non existent WorkflowPersistenceServices. In this case you will find an InnerException with the text "The workflow hosting environment does not have a persistence service as required by an operation on the workflow instance "SomeId"."

.

Depending on the object used to call GetService a number of RuntimeServices might not be returned, a null/Nothing is returned instead. This is the case with a ActivityExecutionContext which will not return any of the following: WorkflowSchedulerService, WorkflowPersistenceService, TrackingService, WorkflowCommitWorkBatchService, WorkflowLoaderService or the WorkflowRuntime itself.

.
Summary
The LoadWorkflowInstanceState method of the WorkflowPersistenceService class is used to load a saved workflow instance back into memory
.

A protected abstract member of the WorkflowPersistenceService class that is implemented in the SqlWorkflowPersistenceService class.

.

The removal of this restriction is a good thing as multiple WorkflowRuntime objects can be useful. The main reason is that different workflow's can have different, and conflicting, requirements of runtime services. And as a single WorkflowRuntime can have only a single runtime service configuration, and that should never be changed while the WorkflowRuntime is active. For example just think of one workflow that is long running and needs a WorkflowPersistenceService while a second is short running and should never be persisted.

.
Summary
.
  • When the WorkflowInstance goes idle and the UnloadOnIdle property if the WorkflowPersistenceService is set.
.

When one of these PersistencePoints is reached the WorkflowRuntime will call the WorkflowPersistenceService SaveWorkflowInstanceState function to persist the workflow.

.

When an Activity adorned with this attribute is used the WorkflowRuntime must be configured with a WorkflowPersistenceService.

.
Summary
.

Collection of objects that actually do most of the work in WF. There are some required services that are always present, if the developer add one that is used otherwise a default is used. For example the DefaultWorkflowSchedulerService is the default implementation of the rquired WorkflowSchedulerService. Some other RuntimeServices are optional but provided out of the box like the SqlWorkflowPersistenceService. If not provided there is no default and this functionality is unavailable. The third kind of RuntimeServices is the custom RuntimeServices usually developed in combination with a custom workflow Activity. These services can use the WorkflowRuntimeService as a base class although this is not required and they can derive from another class is so desired. Use the WorkflowRuntime AddService function to configure the WorkflowRuntime.

.

// Create and add the SqlWorkflowPersistenceService

.

SqlWorkflowPersistenceService persistenceService =

.
   new SqlWorkflowPersistenceService(connectionString);
.
              <add type="System.Workflow.Runtime.Hosting.SqlWorkflowPersistenceService, 
.

One of the main advantages is ClickOnce deployment. In the case of the standard SqlWorkflowPersistenceService you need to have SQL Server installed and running and create the database, with a name of your choosing, using two scripts. Not a big problem but something that needs to be done first and is outside of the realm of what you would like to do with ClickOnce. Not so with SQL Server Compact. No with SqlCe you can just deploy a number of DLL's with your application and you are ready to go, so much easier and very ClickOnce compatible [] Add easy installation is just what you want when you are creating sample applications.

.
                Dim persistence As New SqlCeWorkflowPersistenceService(connectionStr, _
.

Usage is real simple and pretty much the same as the standard SqlWorkflowPersistenceService type. The only extra is to set a reference to the TheProblemSolver.Workflow.Hosting.Persistence.dll that includes the SqlCeWorkflowPersistenceService type.

.
                SqlCeWorkflowPersistenceService persistence = 
.
                    new SqlCeWorkflowPersistenceService(connectionStr, unloadOnIdle, loadingInterval);
.

If you want to download the SqlCeWorkflowPersistenceService you can find it here http://code.msdn.microsoft.com/SqlCeWFPersistence

.
Summary
.
Summary
.

The SqlWorkflowPersistenceService class represents a fully functional persistence service. You can use this service out-of-box to persist and retrieve workflow state information about a workflow instance when requested to by the workflow runtime engine.

.

The SqlWorkflowPersistenceService participates in the workflow transaction batching functionality provided by the WorkflowCommitWorkBatchService. That is, it adds objects that represent pending writes to the SQL database to the WorkBatch and implements the IPendingWork interface.

.

The SqlWorkflowPersistenceService supports locking of workflow instances. This feature is used when several workflow runtimes share the same database. A column in the SQL database table is used to mark a workflow instance as locked whenever it is being used by a workflow runtime. The SqlWorkflowPersistenceService does not load a workflow instance that is marked as "in use" by another runtime. Typically these locks are released when the workflow instance is persisted, for example, on idle, completion, or termination. The locks can also be released automatically after a period of inactivity. This period of inactivity can be set using the constructor of the SqlWorkflowPersistenceService class. It can also be set through the configuration file.

.

For more information about persistence services in general, see the WorkflowPersistenceService class.

.

Workflow instances can contain timers, for example, if they have a DelayActivity. For workflows that contain timers, the SqlWorkflowPersistenceService records the time when the workflow's next timer will expire. The SqlWorkflowPersistenceService periodically polls the database, looking for workflows whose timers have expired. The frequency of the polling interval can be set using the SqlWorkflowPersistenceService constructor or via a configuration file.

.

Derived from WorkflowPersistenceService

.

http://windowssdk.msdn.microsoft.com/en-us/library/system.workflow.runtime.hosting.sqlworkflowpersistenceservice.aspx

.

http://windowssdk.msdn.microsoft.com/en-us/library/system.workflow.runtime.hosting.sqlworkflowpersistenceservice_members.aspx

.

To ensure consistency between the WorkflowInstance and the database being updated the TransactionScopeActivity is adorned with the PersistOnCloseAttribute. When the TransactionScopeActivity is used the WorkflowRuntime must be configured with a WorkflowPersistenceService. This could be the build in SqlWorkflowPersistenceService or another custom WorkflowPersistenceService.

.

Of course you could also use my SqlCeWorkflowPersistenceService as the persistence service, download it from http://code.msdn.microsoft.com/SqlCeWFPersistence. I never did create a TrackingService based upon SQL Compact but if enough people are interested I might just do so

.

Now if you use a WorkBatch to commit the data things work a little different. The WorkBatch is committed in a TransactionScope but this will include the WorkflowPersistenceService itself. So if the workflow runtime crashes before the batch is committed no work is saved at all and everything can safely be repeated. If on the other hand the batch is saved and the workflow runtime crashes after that the workflow will be restarted from the second time it was saved and not repeat the work done.

.
.

The ownership periode of a workflow is determined by the instanceOwnershipDuration paramater of the SqlWorkflowPersistenceService constructor. If this periode has passed the runtime is no longer considered the owner and another runtime os free to load the workflow instance. Additionally if the original runtime will had the workflow loaded and tries to save it a WorkflowOwnershipException will be raised.

.

Calling GetWorkflow to can cause a workflow to be loaded into memory. If the SqlWorkflowPersistenceService is configured with UnloadOnIdle set to true you might expect the workflow to be unloaded automatically but this only happens when the workflow becomes idle. If no activities are executed inside of the workflow it never becomes idle, after all it was idle all the time, and the persistence service never releases its lock on the record.

.

The SqlCeWorkflowPersistenceService is another example of how to implement your own WorkflowPersistenceService.

.

Persistence services are responsible for storing and retrieving (loading and unloading) workflow instance state. WF provides an out-of-box SQL-based implementation of the persistence service: SqlWorkflowPersistenceService.

.
  • WorkflowPersistenceService