locked
Event Exception when Workflow instance is load from persistency! (Urgent) RRS feed

  • Question

  • Hi everyone,

     

    I'm developing a State Machine that manages documents approval and i'm using database persistency (SQLServer).

    If i create a new workflow instance, the application doesn't have any problems and the data is persisted as expected. The big problem occours when I load an instance from the database and start from the last activity persisted. I can launch an event to the last activity persisted but when i get to the next state and launch another event, i get the folowing exception from the LocalService event: Event "AprovacaoExternaDiagnostico" on interface type "WorkflowProcessaProjectos.ISMConnector" for instance id "3fafc57d-97d2-42e4-b0b7-fa48a1e24bbe" cannot be delivered.

     

    The details are:

    System.Workflow.Activities.EventDeliveryFailedException was unhandled by user code
      Message="Event \"AprovacaoExternaDiagnostico\" on interface type \"WorkflowProcessaProjectos.ISMConnector\" for instance id \"3fafc57d-97d2-42e4-b0b7-fa48a1e24bbe\" cannot be delivered."
      Source="System.Workflow.Activities"
      StackTrace:
           at System.Workflow.Activities.WorkflowMessageEventHandler.EventHandler(Object sender, ExternalDataEventArgs eventArgs)
           at WorkflowProcessaProjectos.LocalService.RaiseEvent_AprovacaoExternaDiagnostico(IProcessing p, RegEventArgs e) in C:\Windows Workflow Foundation\Maquina1\LocalService\LocalService\LocalService.cs:line 134
           at MapaProjecto._Default.Button5_Click(Object sender, EventArgs e) in C:\Windows Workflow Foundation\Maquina1\MapaProjecto\Default2.aspx.cs:line 183
           at System.Web.UI.WebControls.Button.OnClick(EventArgs e)
           at System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument)
           at System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument)
           at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument)
           at System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)
           at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

     

    I think that i'm getting correctly the instance from the database (here is the code):

    WorkflowRuntime wr;

    WorkflowInstance wi;

    WorkflowProcessaProjectos.LocalService locSvc;

    ManualWorkflowSchedulerService ms;

    (...)

    SqlWorkflowPersistenceService sqlPersist = wr.GetService<SqlWorkflowPersistenceService>();

    System.Collections.Generic.IEnumerable<SqlPersistenceWorkflowInstanceDescription> PersistedInstances = sqlPersist.GetAllWorkflows();

     

    foreach (SqlPersistenceWorkflowInstanceDescription Instnc in PersistedInstances)

    {

    chave = Instnc.WorkflowInstanceId.ToString().ToUpper();

    if (chave.Equals("3fafc57d-97d2-42e4-b0b7-fa48a1e24bbe".ToUpper()))

    {

    wi = wr.GetWorkflow((Guid)Instnc.WorkflowInstanceId);

    Session["wfi_id"] = wi.InstanceId;

    wi.Load();

    StateMachineWorkflowInstance stateInstance = new StateMachineWorkflowInstance(wr, wi.InstanceId);

    string temp = stateInstance.CurrentStateName;

    if (temp.Equals("Diagnostico"))

    IsDiagnosticoStep = true;

    if (temp.Equals("AprovInternaDiagn"))

    IsAprovacaoInternaStep = true;

    if (temp.Equals("AprovExternaDiagn"))

    IsAprovacaoExternaStep = true;

    wi.Resume();

    }

    }

    ms = wr.GetService<ManualWorkflowSchedulerService>();

    locSvc = wr.GetService<WorkflowProcessaProjectos.LocalService>();

    ms.RunWorkflow(wi.InstanceId);

     

    (...)

     

    Another detail: I'm using ASP.NET to build the aplication that interacts with the workflow.

     

    I've already look for some common problems and i already have the RegEventArgs Serialized and the WaitForIdle set to true, in the LocalService:

    [Serializable]

    public class RegEventArgs : ExternalDataEventArgs

    {

    public RegEventArgs(Guid instance, string command)

    : base(instance)

    {

    this.InstanceId = instance;

    this.Command = command;

    this.WaitForIdle = true;

    }

    private string _command;

    public string Command

    {

    get { return _command; }

    set { _command = value; }

    }

    // User Data

    public string utl_cod;

    public string proj_cod;

    }

     

    I appreciate any help!
     

    Carlos Grosso

    Portugal

    Tuesday, October 23, 2007 3:03 PM

Answers

  • I'd be up for the e-mail challenge, though prevailing manners would require posting the solution (in case you have privacy restrictions at your job).

    First up though:
    Are your services themselves serializable?  If you call them and they become part of the context, they might need to be.
    Are you using correlation?
    Are you launching any other related workflows or have any convoluted activity binds?  Believe it or not I had a situation where I had an error in a workflow (it was a triangular databind that became a circle), where the error manifested as a failure to resolve an activityId that existed within the child workflow, but was thrown in the PARENT.  The child workflow persisted without error and could even be resurrected and responded to events.

    Monday, October 29, 2007 3:57 PM

All replies

  • Are you sure that all of the workflow that you get back are in the same state?  If you haven't already tried this I would re-run the SqlPersistenceService_Schema.sql to drop and re-create your persistence tables.  Warning:  this will delete all of your data; either backup the db first (so that you can restore it later) or create a new db for this test if you can't lose the existing data.  Then re-run your scenario.

     

    If this still fails with a clean db does the scenario work if you remove persistence from the scenario (don't configure a persistence service, just keep the instances in memory).

     

    Thanks,
    Joel West
    MSFTE - SDE

    This posting is provided "AS IS" with no warranties, and confers no rights

     

    Tuesday, October 23, 2007 5:11 PM
  • Hello, i've already done that... It didn't work... Now sometimes i have exceptions with new workflow instances...

    Is there any possibility if you can read my source code and try to discover where the problem is?

    (If there is any possibility i'll can send it by email...)

     

    I'm around this issue for 3 days and I can't find the source of the problem (debug after debug)... I'm becoming desperated...

    Wednesday, October 24, 2007 10:45 PM
  • Have you tried turning on tracking to watch the execution progress of your workflows?  You could use either the SqlTrackingService or the sample (SDK) ConsoleTrackingService to watch what is happening to your instance (i.e. activity what states they pass through).  You can also see if any exceptions are occuring that might put them back into a state where they are not ready to accept the message you are sending them (a state where the queue has not been created).  If you use the SqlTrackingService there is also a sample called WorkflowMonitor that provides a GUI over the data in the tracking database.

     

    Thanks,
    Joel West
    MSFTE - SDE

    This posting is provided "AS IS" with no warranties, and confers no rights

    Saturday, October 27, 2007 12:51 AM
  • I'd be up for the e-mail challenge, though prevailing manners would require posting the solution (in case you have privacy restrictions at your job).

    First up though:
    Are your services themselves serializable?  If you call them and they become part of the context, they might need to be.
    Are you using correlation?
    Are you launching any other related workflows or have any convoluted activity binds?  Believe it or not I had a situation where I had an error in a workflow (it was a triangular databind that became a circle), where the error manifested as a failure to resolve an activityId that existed within the child workflow, but was thrown in the PARENT.  The child workflow persisted without error and could even be resurrected and responded to events.

    Monday, October 29, 2007 3:57 PM
  • Hi.

     

    I have a same issues with one example that I am using (from Pro WF by Bukovics, C:\ProWF\chapter 08\bin\PersistenceDemo.exe). In some cases when I am trying to "send an event" to specific instance of the WF I get the simmilar thing:

     

    System.Workflow.Activities.EventDeliveryFailedException: Event "ContinueReceived" on interface type "SharedWorkflows.IPersistenceDemo" for instance id "512da25d-e147-481f-88bf-24d046a331b7" cannot be delivered. ---> System.IndexOutOfRangeException: Index was outside the bounds of the array.
       at System.Workflow.ComponentModel.Serialization.ActivitySurrogate.ActivitySerializedRef.System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(Object sender)
       at System.Runtime.Serialization.DeserializationEventHandler.Invoke(Object sender)
       at System.Runtime.Serialization.ObjectManager.RaiseDeserializationEvent()
       at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
       at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
       at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)
       at System.Workflow.ComponentModel.Activity.Load(Stream stream, Activity outerActivity, IFormatter formatter)
       at System.Workflow.ComponentModel.Activity.Load(Stream stream, Activity outerActivity)
       at System.Workflow.Runtime.Hosting.WorkflowPersistenceService.RestoreFromDefaultSerializedForm(Byte[] activityBytes, Activity outerActivity)
       at System.Workflow.Runtime.Hosting.SqlWorkflowPersistenceService.LoadWorkflowInstanceState(Guid id)
       at System.Workflow.Runtime.WorkflowRuntime.InitializeExecutor(Guid instanceId, CreationContext context, WorkflowExecutor executor, WorkflowInstance workflowInstance)
       at System.Workflow.Runtime.WorkflowRuntime.Load(Guid key, CreationContext context, WorkflowInstance workflowInstance)
       at System.Workflow.Runtime.WorkflowRuntime.GetWorkflow(Guid instanceId)
       at System.Workflow.Activities.WorkflowMessageEventHandler.EventHandler(Object sender, ExternalDataEventArgs eventArgs)
    ...

     

    I am not sure what is it that I am doing wrong...

     

    Thanks,

     

    P.

    Monday, October 29, 2007 4:47 PM