locked
Error in WF 4.0 Beta 2 RRS feed

  • Question

  • Hello!

    I think I've found an error in WF 4.0 Beta 2. In order to document the error I've modified the Persistence sample very little:
    *) Wrapped the body in a for loop so a lot of WorkflowApplication instances will be made and run.
    *) Turn readline into a counter, so it may operate at its own pace.

    When I run this program I always receive an exception after a number of iterations. It may for instance be after 90,000 iterations. A running of the program always results in exceptions. The exceptions do not occur after the same number of iterations at each run.

    I obviously hope that somebody at Microsoft would like to try this code and either tell what is wrong in my code, i.e. basically in the Persistence sample, or that there indeed is an error in WF 4.0 Beta 2 and if it'll be corrected in the next drop. The database in use is obviously made according to the directions for Beta 2.

    This is the entire contents of the Program.cs file:

    //----------------------------------------------------------------
    
    // Copyright (c) Microsoft Corporation.  All rights reserved.
    
    //----------------------------------------------------------------
    
    
    
    namespace Microsoft.Samples.Activities
    
    {
    
        using System;
    
        using System.Activities;
    
        using System.Activities.DurableInstancing;
    
        using System.Activities.Statements;
    
        using System.Runtime.Persistence;
    
        using System.Threading;
    
        using System.Collections.Generic;
    
        using System.Configuration;
    
    
    
        class Program
    
        {
    
            static InstanceStore instanceStore;
    
            static AutoResetEvent instanceUnloaded = new AutoResetEvent(false);
    
            //static Activity activity = CreateWorkflow();
    
            static Guid id;
    
    
    
            const string readLineBookmark = "ReadLine1";
    
    
    
            static void SetInfo(string info)
    
            {
    
                Console.WriteLine(info);
    
            }
    
    
    
            static void Main()
    
            {
    
                SetupInstanceStore();
    
    
    
                for (int i = 0; i < 1000000; i++)
    
                {
    
                    StartAndUnloadInstance();
    
                    LoadAndCompleteInstance();
    
                }
    
    
    
                Console.WriteLine("Press [Enter] to exit.");
    
                Console.ReadLine();
    
            }
    
    
    
            static void StartAndUnloadInstance()
    
            {
    
                Activity activity = CreateWorkflow();
    
                WorkflowApplication application = new WorkflowApplication(activity);
    
    
    
                application.InstanceStore = instanceStore;
    
    
    
                //returning IdleAction.Unload instructs the WorkflowApplication to persists application state and remove it from memory  
    
                application.PersistableIdle = (e) =>
    
                    {
    
                        return PersistableIdleAction.Unload;
    
                    };
    
    
    
                application.Unloaded = (e) =>
    
                    {
    
                        instanceUnloaded.Set();
    
                    };
    
    
    
    
    
                //This call is not required 
    
                //Calling persist here captures the application durably before it has been started
    
                application.Persist();
    
                id = application.Id;
    
                application.Run();
    
    
    
                instanceUnloaded.WaitOne();
    
            }
    
    
    
            static long currentOrdinalValue = 0;
    
    
    
            static void LoadAndCompleteInstance()
    
            {
    
                //string input = Console.ReadLine();
    
                string input = System.Threading.Interlocked.Increment(ref currentOrdinalValue).ToString();
    
    
    
                Activity activity = CreateWorkflow();
    
                WorkflowApplication application = new WorkflowApplication(activity);
    
                application.InstanceStore = instanceStore;
    
    
    
                application.Completed = (workflowApplicationCompletedEventArgs) =>
    
                {                
    
                    Console.WriteLine("\nWorkflowApplication has Completed in the {0} state.", workflowApplicationCompletedEventArgs.CompletionState);
    
                };
    
    
    
                application.Unloaded = (workflowApplicationEventArgs) =>
    
                {
    
                    Console.WriteLine("WorkflowApplication has Unloaded\n");
    
                    instanceUnloaded.Set();
    
                };
    
    
    
                application.Load(id);
    
    
    
                //this resumes the bookmark setup by readline
    
                application.ResumeBookmark(readLineBookmark, input);
    
    
    
                instanceUnloaded.WaitOne();
    
            }
    
    
    
            static Sequence CreateWorkflow()
    
            {
    
                Variable<string> response = new Variable<string>();
    
    
    
                return new Sequence()
    
                {
    
                    Variables = { response },
    
                    Activities = { 
    
                            new WriteLine(){
    
                                Text = new InArgument<string>("What is your name?")},
    
                            new ReadLine(){ 
    
                                BookmarkName = readLineBookmark, 
    
                                Result = new OutArgument<string>(response)},
    
                            new WriteLine(){
    
                                Text = new InArgument<string>((context) => "Hello " + response.Get(context))}}
    
                };
    
            }
    
    
    
            private static void SetupInstanceStore()
    
            {
    
                //instanceStore = 
    
                //    new SqlWorkflowInstanceStore(@"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\SampleInstanceStore.mdf;Integrated Security=True;User Instance=True");
    
                instanceStore =
    
                    new SqlWorkflowInstanceStore(@"Data Source=.;Initial Catalog=Persistence;Integrated Security=True;MultipleActiveResultSets=True;Async=true");
    
    
    
                InstanceView view = instanceStore.Execute(instanceStore.CreateInstanceHandle(), new CreateWorkflowOwnerCommand(), TimeSpan.FromSeconds(30));
    
                instanceStore.DefaultInstanceOwner = view.InstanceOwner;
    
            }
    
        }
    
    }<br/>
    
    


    This shows the exceptions from a concrete run:
    Unhandled Exception:                                                                                                                                                                WorkflowApplication has Completed in the Closed state.                                                                                                                              Unhandled Exception:Unhandled Exception:  System.InvalidOperationException: An incorrect implementation of the IAsyncResult interface may be returning incorrect values from the CompletedSynchronously property or calling the AsyncCallback more than once. The type System.Data.Common.DbAsyncResult could be the incorrect implementation.                          
    
       at System.Runtime.AsyncResult.AsyncCompletionWrapperCallback(IAsyncResult result)                                                                                                   at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)                                                                                                        at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)                                       
    
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)                                                              
    
       at System.Data.Common.DbAsyncResult.ExecuteCallback(Object asyncResult)                                                                                                             at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)                                       
    
       at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()                                                                             
    
       at System.Threading.ThreadPoolWorkQueue.Dispatch()                                                                                                                                  at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
    
    System.InvalidOperationException: An incorrect implementation of the IAsyncResult interface may be returning incorrect values from the CompletedSynchronously property or calling the AsyncCallback more than once. The type System.Data.Common.DbAsyncResult could be the incorrect implementation.                                                                                                                                                                                       at System.Runtime.AsyncResult.AsyncCompletionWrapperCallback(IAsyncResult result)                                                                                                   at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)                                                                                                        at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)                                       
    
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)                                                              
    
       at System.Data.Common.DbAsyncResult.ExecuteCallback(Object asyncResult)                                                                                                             at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)                                       
    
       at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()                                                                             
    
       at System.Threading.ThreadPoolWorkQueue.Dispatch()                                                                                                                                  at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()WorkflowApplication has Unloaded                                                                                
    
    



    Best regards.

    Henrik Dahl

    Thursday, November 12, 2009 3:38 PM

All replies

  • Hello,

    The workflow that you have is already complete when its attempted to be loaded again. The instance should be in the runnable state in the persistence database to be loaded again. Also, you are sharing the wait events across all the 100000 instances which means there can be just one instance running anytime while we block for the event to be returned. I see the callstack of the failure but there is no exception in there. Can you please point to the actual sample and the exception?

    Thanks.

    Friday, November 13, 2009 7:45 PM
  • UmeshMR,

    Concerning "The workflow that you have is already complete when its attempted to be loaded again.": Can't you explain it more, please. This is exactly the code from the samples from "Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) Samples for .NET Framework 4.0 Beta 2" in the folder: "VS2010Samples\WF_WCF_Samples\WF\Basic\Persistence" so I suppose there should be no problem here.

    Concerning "Also, you are sharing the wait events across all the 100000 instances which means there can be just one instance running anytime while we block for the event to be returned.": Yes, but this is no problem as they're all executed in sequence by the conventional for loop.

    Concerning "Can you please point to the actual sample and the exception?": What do you mean with "and the exception"? (the exception seems to come from inside the WF 4.0 stuff.). You may see more details if you run it from a command prompt and not from within the VS 2010 IDE.


    Best regards,

    Henrik Dahl
    Friday, November 13, 2009 8:13 PM
  • Hello!

    Isn't there some from Microsoft who would like to try the code at the top and report if they also receive exceptions after some iterations and, if yes, if the exceptions denote a problem which will be corrected, please?


    Best regards,

    Henrik Dahl
    Wednesday, November 18, 2009 6:49 PM