locked
Execution Locked RRS feed

  • Question

  • I'm having an issue resuming a bookmark, not sure if I'm going this right...

    Here's the error:

     

    The execution of an InstancePersistenceCommand was interrupted because the instance '34eb8358-062d-4467-b1c2-3a54ff3937db' 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 '59385505-9fb8-4872-b55b-1fd1eaf437d7'.

    <em><em>/* ACTIVITY WHICH PERSISTS */
    
    ...
    public
     InArgument<string
    > ApprovalID { get
    ; set
    ; }
    
    protected
     override
     void
     Execute(NativeActivityContext context) {
     var
     bookmark = context.CreateBookmark("ApprovalBookmark"
    , BookmarkResumed);
    }
    
    private
     void
     BookmarkResumed(NativeActivityContext context, Bookmark bookmark, object
     value) {
    	Guid approvalID = new
     Guid(ApprovalID.Get(context)); //Never get here
    
    }
    ...
    
    
    /* PAGE WHICH SHOULD RESUME */
    
    ...
    var
     wa = new
     WorkflowApplication(new
     SendApprovalEmail());
    
    var
     instanceStore = new
     SqlWorkflowInstanceStore(_connString);
    wa.InstanceStore = instanceStore;
    
    wa.Load(this
    .InstanceID); // This is where the error happens (instance ID saved to the DB via context.WorkflowInstanceId)
    
    
    var
     data = RTO.Workflow.ActivityLibrary.RequestState.Approved;
    wa.ResumeBookmark("ApprovalBookmark"
    , data);
    ...</em>
    </em>
    
    
    
    

     

    Tuesday, May 25, 2010 4:35 PM

All replies

  • Ok, after some screwing around, Im now stuck with this one :D (I think this is what changed it wa.PersistableIdle = (callback) => PersistableIdleAction.Unload;)

     

     

    'SendApprovalEmail' is not of type 'DynamicActivity'. When loading this instance you must ensure that the activity with name 'SendApprovalEmail' implements 'DynamicActivity'.


    Tuesday, May 25, 2010 6:03 PM
  • For the first issue, yes, you need unload a workflow before you load it again.

    For the second issue, is the root activity of the persisted workflow activity SendApprovalEmail?

    Wednesday, May 26, 2010 2:26 PM
  • I switched the Bookmarking out of SendApprovalEmail and over to a step after that in the flowchart

     

    So here's the wait code...

     public sealed class WaitForApproval : NativeActivity {
      public WaitForApproval() : base() {
      }
    
      public InArgument<string> ApprovalID { get; set; }
      public OutArgument<string> Input { get; set; }
    
      protected override void Execute(NativeActivityContext context) {
       context.CreateBookmark("WaitForApproval", new BookmarkCallback(this.ResumeBookmark));
      }
    
      void ResumeBookmark(NativeActivityContext context, Bookmark bookmark, object value) {
       IObjectScope scope = ObjectScopeProvider1.GetNewObjectScope();
       scope.Transaction.Begin();
    
       IDictionary<string, object> data = value as Dictionary<string, object>;
    
       Guid approvalID = new Guid(data["ApprovalID"].ToString());
       RequestState state = (RequestState)data["Status"];
    
       try {
        RTODataLayer.Approval approval = scope.Extent<RTODataLayer.Approval>().Where(x => x.ApprovalID == approvalID).FirstOrDefault();
        approval.StatusID = Convert.ToInt16(state);
    
        scope.Transaction.Commit();
       } catch (Exception ex) {
    
       } finally {
        scope.Dispose();
       }
      }
    
      protected override bool CanInduceIdle { get { return true; } }
     }

     

    And in the page here's what I'm doing to resume it...but I never get here because the Load (passing in the instance id below) fails

    protected void Approve_Click(object sender, EventArgs e) {
       try {
        WorkflowApplication wa = new WorkflowApplication(new WaitForApproval());
    
        SqlWorkflowInstanceStore instanceStore = new SqlWorkflowInstanceStore();
        wa.InstanceStore = instanceStore;
        wa.Load(this.InstanceID);
        
        IDictionary<string, object> InArgs = new Dictionary<string, object>();
        InArgs.Add("Status", RTO.Workflow.ActivityLibrary.RequestState.Approved);
        InArgs.Add("ApprovalID",this.ApprovalID);
    
        BookmarkResumptionResult result = wa.ResumeBookmark("WaitForApproval", InArgs);
        
        debugLabel.Text = result.ToString();
       } catch (Exception ex) {
        debugLabel.Text = ex.ToString();
       } finally {
    
       }
      }

    And this Starts the flow (well I see persisted data in the DB anyway)

     

    IDictionary<string, object> InArgs = new Dictionary<string, object>();
    
    Activity workflow = ActivityXamlServices.Load(Server.MapPath(workflowBox.SelectedValue));
    WorkflowApplication app = new WorkflowApplication(workflow, InArgs);
    
    InArgs.Add("RequestID", newRequest.RequestID.ToString());
    
    SqlWorkflowInstanceStore instanceStore = new SqlWorkflowInstanceStore(_connString);
    app.InstanceStore = instanceStore;
    
    app.Run(); //Run the application

     

     

    Wednesday, May 26, 2010 2:41 PM
  • Hi, Steve

    ->"SqlWorkflowInstanceStore instanceStore = new SqlWorkflowInstanceStore();
        wa.InstanceStore = instanceStore;
        wa.Load(this.InstanceID);
    "
    I don't see a sql database connection strin here. are you sure it is the right code?

    If you want to load persisted workflow instance across workflow applications, You would also need to se the DefaultInstanceOwner property of SqlWFInstanceStore. Here is a sample:

            private static SqlWorkflowInstanceStore SetupSqlpersistenceStore() {

                string connectionString = ConfigurationManager.AppSettings["SqlWF4PersistenceConnectionString"].ToString();

                SqlWorkflowInstanceStore sqlWFInstanceStore = new SqlWorkflowInstanceStore(connectionString);

                InstanceHandle handle = sqlWFInstanceStore.CreateInstanceHandle();

                InstanceView view = sqlWFInstanceStore.Execute(handle, new CreateWorkflowOwnerCommand(), TimeSpan.FromSeconds(5));

                handle.Free();

                sqlWFInstanceStore.DefaultInstanceOwner = view.InstanceOwner;// if not set the instance store will be garbage collected

                return sqlWFInstanceStore;

            }

    Hope this helps
    Regards

     

     


    This posting is provided "AS IS" with no warranties, and confers no rights. Microsoft Online Community Support
    Thursday, May 27, 2010 6:12 AM
  • For initial workflow, it used an dynamic activity which is returned by ActivityXamlServices.Load(Server.MapPath(workflowBox.SelectedValue) to represent your flowchart. In loading, you shoud use the same activity definition. 
    Thursday, May 27, 2010 6:32 AM