HemantC

hi,

Is there any way to start the HandleExternalEventActivity from the workflow itself rather waiting for event from Host.

Since its the mandatory activity for a state.

After Transition from my current state I want to directly start a while loop in a new state rather waiting for a event from host.

Is there a solution for this.

thanks

Hemant




Re: Windows Workflow Foundation State Machine and HandleExternalEventActivity

Robert Wilczynski

Hi Hermant,

Since I don't know how you workflow is structured I can only answer the first part of the question (it might be that there is a different solution depending on how your workflow is built). I would suggest a custom activity which would look something like this:

43 public class RaiseEventActivity : Activity

44 {

45 protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)

46 {

47 MyExternalDataExchangeService service = executionContext.GetService<MyExternalDataExchangeService>();

48 MyEventArgs args = new MyEventArgs(this.WorkflowInstanceId);

49 args.WaitForIdle = true;

50 service.RaiseEvent(args);

51 return ActivityExecutionStatus.Closed;

52 }

53 }


Assuming you have the following defined:

18 [Serializable]

19 public class MyEventArgs : ExternalDataEventArgs

20 {

21 public MyEventArgs(Guid instanceId) : base(instanceId) { /* */ }

22 }

23

24 [ExternalDataExchange]

25 interface IMyExternalDataExchangeService

26 {

27 event EventHandler<MyEventArgs> EventHappened;

28 void RaiseEvent(MyEventArgs args);

29 }

30

31 [Serializable]

32 public class MyExternalDataExchangeService : IMyExternalDataExchangeService

33 {

34 public event EventHandler<MyEventArgs> EventHappened;

35

36 public void RaiseEvent(MyEventArgs args)

37 {

38 if (EventHappened != null)

39 EventHappened(this, args);

40 }

41 }


I believe you could also do it by using CallExternalMethodActivity if your IMyExternalDataExchangeService actually defines a method for raising an event (RaiseEvent in my example).

Let me know if that helps,

Best reagrds,
Robert Wilczynski.





Re: Windows Workflow Foundation State Machine and HandleExternalEventActivity

HemantC

hi Robert ,

thanks for the reply.

1 more question i want to ask.Is there any Switch case kind of activity or i need to develop that

thanks

Hemant






Re: Windows Workflow Foundation State Machine and HandleExternalEventActivity

Robert Wilczynski

There is no switch activity shipped with WF but you can find one here:

http://wf.netfx3.com/files/folders/control_flow/entry5372.aspx

Best regards,
Robert Wilczynski.






Re: Windows Workflow Foundation State Machine and HandleExternalEventActivity

HemantC

Hi Robert,

your raiseeventactivity logic doesnot work.it gives me error that Eevent cannot be delivered.

Can you please hep on this

thanks

Hemant






Re: Windows Workflow Foundation State Machine and HandleExternalEventActivity

Roman Kiss

Hemant,

- For raising an event cross the State, the custom workflow runtime service can help you. See this thread.

Thanks

Roman






Re: Windows Workflow Foundation State Machine and HandleExternalEventActivity

Robert Wilczynski

Hi Hermant,

First of all try making the IMyExternalDataExchangeService interface public and use it when configuring the HandleExternalEvent activity instead of the concrete class.

You are right, it seems the approach I gave you won't work - for some reason you can't fire an event on the workflow thread. So you can do what Roman suggested (Roman - thanks for your help):

1. Create a runtime service:

public class EventInvoker : WorkflowRuntimeService

{

public void RaiseEvent(MyEventArgs args)

{

MyExternalDataExchangeService service = base.Runtime.GetService<MyExternalDataExchangeService>();

service.RaiseEvent(args);

}

}


2. Modify the custom activity:

public class RaiseEventActivity : Activity

{

protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)

{

EventInvoker invoker = executionContext.GetService<EventInvoker>();

invoker.RaiseEvent(new MyEventArgs(this.WorkflowInstanceId));

return ActivityExecutionStatus.Closed;

}

}

3. Add the service to the WorkflowRuntime instance:

workflowRuntime.AddService(new EventInvoker());


Alternatively this approach seems to work but I would reccomend external runtime service anyway:

public class RaiseEventActivity : Activity

{

public class ThreadParameters

{

private IMyExternalDataExchangeService _service;

public IMyExternalDataExchangeService Service

{

get { return _service; }

set { _service = value; }

}

private Guid _workflowInstanceId;

public Guid WorkflowInstanceId

{

get { return _workflowInstanceId; }

set { _workflowInstanceId = value; }

}

public ThreadParameters(IMyExternalDataExchangeService service, Guid workflowInstanceId)

{

_service = service;

_workflowInstanceId = workflowInstanceId;

}

}


protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)

{

IMyExternalDataExchangeService service = executionContext.GetService<IMyExternalDataExchangeService>();

Thread thread = new Thread(new ParameterizedThreadStart(

delegate(object parameter)

{

ThreadParameters threadParameters = parameter as ThreadParameters;

MyEventArgs args = new MyEventArgs(threadParameters.WorkflowInstanceId);

args.WaitForIdle = true;

threadParameters.Service.RaiseEvent(args);

}));

thread.Start(new ThreadParameters(service, this.WorkflowInstanceId));

return ActivityExecutionStatus.Closed;


}

}


Sorry for the inconvenience that my previous answer has caused.

Best regards,
Robert Wilczynski.