问题
When attempting to Resume a Workflow with the following code:
public WorkflowApplication LoadInstance(Guid instanceId)
{
if (this.instances.ContainsKey(instanceId))
return this.instances[instanceId];
WorkflowApplication instance = new WorkflowApplication(new Tarpon.Workflows.CreateContact());
// Create Persistable Workflow
SqlWorkflowInstanceStore store = new SqlWorkflowInstanceStore(ConfigurationManager.ConnectionStrings["WorkflowPersistance"].ConnectionString);
store.HostLockRenewalPeriod = new TimeSpan(0, 0, 5);
instance.InstanceStore = store;
// Load Instance
instance.Completed += OnWorkflowCompleted;
instance.Idle += OnIdle;
instance.PersistableIdle += OnIdleAndPersistable;
instance.Aborted += OnAborted;
instance.Load(instanceId);
// Save instance in list of running instances
this.instances.Add(instance.Id, instance); // ERROR IS THROWN HERE
return instance;
}
I get and error on the line "this.instances.Add(instance.Id, instance)":
The execution of an InstancePersistenceCommand was interrupted because the instance '9b9430b6-f182-469d-bcae-0886d546f7ea' is locked by a different instance owner.
This error usually occurs because a different host has the instance loaded. The instance owner ID of the owner or host with a lock on the instance is '30411662-b9b3-4250-9e2c-5aaa9895b740'.
I have attempted to lower the HostLockRenewalPeriod in the above code, and also added the below code to hopefully disable the lock on the Instance but to no avail. It also never seems to break into the below code. Every time I go past the Load() method, I get th above error.
public PersistableIdleAction OnIdleAndPersistable(WorkflowApplicationIdleEventArgs e)
{
instances.Remove(e.InstanceId);
return PersistableIdleAction.Unload;
}
It seems this code works half the time, but the other half it does not resume it's workflows correctly. Does anyone have any clue to what I can do to remove the lock properly, without having to re-write all of this functionality?
回答1:
Please take a look at this blog post describing persistance and instaneStore confiuration.
This code is copied from the post and I think it might help you: "
var instanceStore = new SqlWorkflowInstanceStore(connStr);
var instanceHandle = instanceStore.CreateInstanceHandle();
var createOwnerCmd = new CreateWorkflowOwnerCommand();
var view = instanceStore.Execute(instanceHandle, createOwnerCmd, TimeSpan.FromSecond(30));
instanceStore.DefaultInstanceOwner = view.InstanceOwner;
// Do whatever needs to be dome with multiple WorkflowApplications
var deleteOwnerCmd = new DeleteWorkflowOwnerCommand();
instanceStore.Execute(instanceHandle, deleteOwnerCmd, TimeSpan.FromSeconds(30));
The key is the CreateWorkflowOwnerCommand that needs to be executed at the start. And when you use the CreateWorkflowOwnerCommand just make sure not to forget the DeleteWorkflowOwnerCommand otherwise all workflow will remain locked by the owner and can’t be reloaded by another SqlWorkflowInstanceStore
回答2:
I don't see instance.Run
or instance.ResumeBookmark
here, and you'll need that for any execution-related events like PersistableIdle to be fired.
回答3:
Actually, when I've seen this error in development, it just means I need to clean out my persistence database. You can do that with a stored procedure that already exists to delete a persisted workflow.
回答4:
Try making a WorkflowIdleBehavior
object and setting it's TimeToUnload
to zero. See here for more details.
来源:https://stackoverflow.com/questions/10729383/error-when-attempting-to-resume-a-windows-workflow