2016-09-27 2 views
0

Я создаю Workflow application with persistent behaviour and two bookmarks.WF постоянство с двумя закладками. не удалось сохранить вторую закладку

Мне не удается сохранить рабочую среду для второй закладки.

Workflow заявление

1- Start workflow 
2- Ask user to enter name 
3- Create bookmark 
4- Resume bookmark on receiving input from user and show it on UI 
5- Ask user again to enter number 
6- Create bookmark and wait for user input // Unable to persist at this point 
7- Resume bookmark on receiving input from user and show it on UI 

Пользовательские активность

public class WaitForInput<TResult> : NativeActivity<TResult> 
{ 
    [RequiredArgument] 
    public InArgument<string> BookmarkName { get; set; } 

    // indicate to the runtime that this activity can go idle 
    protected override bool CanInduceIdle 
    { 
     get { return true; } 
    } 

    protected override void Execute(NativeActivityContext context) 
    {       
     context.CreateBookmark(this.BookmarkName.Get(context), new BookmarkCallback(OnReadComplete)); 
    } 

    void OnReadComplete(NativeActivityContext context, Bookmark bookmark, object state) 
    {    
     this.Result.Set(context, (TResult)state); 
    } 
} 

Program.cs

class Program 
{ 
    static AutoResetEvent syncEvent = new AutoResetEvent(false); 
    static Guid id; 

    static void Main(string[] args) 
    { 
     WorkflowApplication app = new WorkflowApplication(new Sequence1()); 
     InstanceStore store = new SqlWorkflowInstanceStore(@"Data Source=.\SQLEXPRESS;Initial Catalog=WF45GettingStartedTutorial;Integrated Security=True"); 
     InstanceHandle handle = store.CreateInstanceHandle(); 
     InstanceView view = store.Execute(handle, new CreateWorkflowOwnerCommand(), TimeSpan.FromSeconds(30)); 
     handle.Free(); 
     store.DefaultInstanceOwner = view.InstanceOwner; 
     app.InstanceStore = store; 


     app.PersistableIdle = delegate(WorkflowApplicationIdleEventArgs e) 
     { 
      return PersistableIdleAction.Unload; 

     }; 

     app.Unloaded = delegate(WorkflowApplicationEventArgs e) 
     { 
      syncEvent.Set(); 
     }; 

     app.Completed = delegate(WorkflowApplicationCompletedEventArgs e) 
     { 
      Console.WriteLine("Workflow {0} Completed.", e.InstanceId); 
     }; 

     id = app.Id; 
     app.Run(); 
     syncEvent.WaitOne(); 

     string text = Console.ReadLine(); 
     app = new WorkflowApplication(new Sequence1()); 
     app.InstanceStore = store; 

     app.Completed = (workflowApplicationCompletedEventArgs) => 
     { 
      Console.WriteLine("WF Bookmark1 has Completed in the {0} state.", 
           workflowApplicationCompletedEventArgs.CompletionState); 
     }; 
     app.Unloaded = (workflowApplicationEventArgs) => 
     { 
      Console.WriteLine("WF Bookmark1 unloaded"); 
      syncEvent.Set(); 
     }; 

     app.Load(id); 
     app.ResumeBookmark("readText", text); 
     syncEvent.WaitOne(); 

     // resume bookmark 2 
     int number = ReadNumberFromConsole(); 
     app = new WorkflowApplication(new Sequence1()); 
     app.InstanceStore = store; 
     app.Completed = (workflowApplicationCompletedEventArgs) => 
     { 
      Console.WriteLine("WF Bookmark2 has Completed in the {0} state.", 
           workflowApplicationCompletedEventArgs.CompletionState); 
     }; 
     app.Unloaded = (workflowApplicationEventArgs) => 
     { 
      Console.WriteLine("WF Bookmark1 unloaded"); 
      syncEvent.Set(); 
     }; 

     app.Load(id); 
     app.ResumeBookmark("readNumber", number); 
     syncEvent.WaitOne(); 
     Console.ReadLine(); 
    }  


} 

Проблема Workflow выполнение запрашивает у пользователя ввести имя и создавать закладки и вызовы PersistableIdleAction.Unload

После того как я вошел имя пользователя на консоли, это перезагружает экземпляр рабочего процесса и возобновить закладку.

Это не называется PersistableIdleAction.Unload для следующего вида деятельности.

Просьба помочь

+0

@Maurice, извините, что направляете вас, но не могли бы вы посмотреть и ответить? – immirza

ответ

0

Проблема была с multi threading concept здесь.

app.Run(); 

Над линией начала рабочего процесса выполнения на новом потоке, так как я ссылающегося на него с помощью WorkflowApplication (и не WorkflowInvoker).

При создании 1-й закладки рабочий процесс был сохранен & выгружен из этой темы.

Я создавал новую рабочую среду при возобновлении над закладкой, и поэтому у нее разные темы.

Solution: I should persist & unload workflow from this thread and not from the 1st first thread. 

Я учусь, это может быть неправильно где-то, но, честно говоря, это то, что я понял, потратив много времени на это.

Правильная версия Program.cs

namespace Microsoft.Samples.Activities.Statements 
{ 

    class Program 
    { 
     static AutoResetEvent syncEvent = new AutoResetEvent(false); 
     static Guid id; 

     static void Main(string[] args) 
     { 
      // create the workflow app and add handlers for the Idle and Completed actions 
      WorkflowApplication app = new WorkflowApplication(new Sequence1()); 

      //setup persistence 
      InstanceStore store = new SqlWorkflowInstanceStore(@"Data Source=.\SQLEXPRESS;Initial Catalog=WF45GettingStartedTutorial;Integrated Security=True"); 
      InstanceHandle handle = store.CreateInstanceHandle(); 
      InstanceView view = store.Execute(handle, new CreateWorkflowOwnerCommand(), TimeSpan.FromSeconds(30)); 
      handle.Free(); 
      store.DefaultInstanceOwner = view.InstanceOwner; 
      app.InstanceStore = store; 


      app.PersistableIdle = delegate(WorkflowApplicationIdleEventArgs e) 
      { 
       syncEvent.Set(); 
       return PersistableIdleAction.Unload; 

      }; 

      app.Unloaded = delegate(WorkflowApplicationEventArgs e) 
      { 
       syncEvent.Set(); 
      }; 

      app.Completed = delegate(WorkflowApplicationCompletedEventArgs e) 
      { 
       Console.WriteLine("Workflow {0} Completed.", e.InstanceId); 
       syncEvent.Set(); 
      }; 

      // start the application 
      id = app.Id; 
      app.Run(); 
      syncEvent.WaitOne(); 

      // resume bookmark 1 
      string text = Console.ReadLine(); 
      app = new WorkflowApplication(new Sequence1()); 
      app.InstanceStore = store; 

      app.PersistableIdle = delegate(WorkflowApplicationIdleEventArgs e) 
      { 
       syncEvent.Set(); 
       return PersistableIdleAction.Unload; 

      }; 

      app.Completed = (workflowApplicationCompletedEventArgs) => 
      { 
       Console.WriteLine("WF Bookmark1 has Completed in the {0} state.", 
            workflowApplicationCompletedEventArgs.CompletionState); 
       syncEvent.Set(); 
      }; 
      app.Unloaded = (workflowApplicationEventArgs) => 
      { 
       Console.WriteLine("WF Bookmark1 unloaded"); 
       syncEvent.Set(); 
      }; 

      app.Load(id); 
      app.ResumeBookmark("readText", text); 
      syncEvent.WaitOne(); 

      // resume bookmark 2 
      int number = ReadNumberFromConsole(); 
      app = new WorkflowApplication(new Sequence1()); 
      app.InstanceStore = store; 
      app.Completed = (workflowApplicationCompletedEventArgs) => 
      { 
       Console.WriteLine("WF Bookmark2 has Completed in the {0} state.", 
            workflowApplicationCompletedEventArgs.CompletionState); 
       syncEvent.Set(); 
      }; 
      app.Unloaded = (workflowApplicationEventArgs) => 
      { 
       Console.WriteLine("WF Bookmark1 unloaded"); 
       syncEvent.Set(); 
      }; 

      app.Load(id); 
      app.ResumeBookmark("readNumber", number); 
      syncEvent.WaitOne(); 

      Console.WriteLine(""); 
      Console.WriteLine("Press [ENTER] to exit..."); 
      Console.ReadLine(); 
     }   

    } 
} 

Вы можете исправить мою точку здесь. Спасибо

Смежные вопросы