Hi,
I have written a simple state machine which is very similar to the order example comes with WWF Jan Lab Beta 2.
I created the following service
public class NavigationService : INavigationService
{
public event EventHandler<NavigationEventArgs> StartPageStart;
public void RaiseStartPageStartEvent(Guid instanceId)
{
if (StartPageStart != null) //StartPage is null when host calling RaiseStartPageStartEvent
{
StartPageStart(null,new NavigationEventArgs(instanceId));
}
}
In the state workflow, I have bound the "InterfaceType" and "EventName" to the service and StartPageStart Event.
The problem is when I calling the following code in the host (a window form application)
_navigationService.RaiseStartPageStartEvent(workflowInstanceId);
It won't trigger the state change. I traced throught the code and found
StartPageStart is null inside function public void RaiseStartPageStartEvent(Guid instanceId)
Does anyone have any suggestion about how to ping down the problem
Thanks a lot
chong

EventHandler won't fire in state machine when calling event from host
krascso
Chong... email me your solution and I'll take a look.
dennispi@nospam.microsoft.com (remove the nospam)
JHerington
The main thing that jumps out at me is that you call RunWorkflow twice in a row on the ManualSchedulerService. You should only need to call this once, but I don't think it will cause you problems to call it more than once.
The other thing I noticed is that you put the local service in the runtime on each page load. I would expect you to get an error here, but if not, it may be causing you problems. I would move this code to add your local service to an Application_OnStart method or something like it in the asax file.
If you are interested, you can send me your project offline and I will take a look to see if I can get your event to fire. Other things I would look at would be the setup of the state machine to make sure it is ready for the correct event and the web.config file to make sure the correct services are configured.
Matt
Abhishek_Goel
Hi Crp2k4,
You actually dont need to do any of the runtime setup on each page in an ASP.NET app.
If you have a look at the Workflow's WebService Publishing wizard to see how you could setup a ASP.NET Webservice environment - mainly all done in the web.config.
So for ASP.NET, what I do:
(1) declare a global static 'runtime' variable that references the WF runtime engine (as these are hosted within your appdomain)
(2) on the application_onStart event in the global.asax do your runtime initialisation there.
Each page that uses the workflow doesnt have to start it all up and tear it down. This approach assumes that the majority of your pages will use the workflow in some way.
Now for your problem:
The part that doesnt look right for me is:
you create the runtime as a page level variable and fire up your workflow that way (which is fine for a single page use), but then
you grab the current workflow runtime from the webrequest context.
My understanding is that this is only available if you're using the Workflow HTTP module handler - as the request has been intercepted prior to your page getting it, the custom handler has initialised the environment to make that work.
Check a Workflow Webservice example for more detail (in the web.config)
HTH,
Mick
degarmo-tech@messengeruser.com
Hi, Dennis:
Thanks a lot for the help. I have sent you the solution as a zip file.
Please let me know if you need more detail information.
chong
Nicole Calinoiu
Hi, Matt:
Thanks for the reply. That was the problem. I figured it out after comparing my code with the order example comes with Beta 2 lab.
chong
Krako
Are you using the RunWorkflow method on the ManualSchedulingService That is a pretty common problem in beta 2 with asp.net apps.
Also, I have found that running the workflow from a test host might help you find problems that you can't find as easily in asp.net. The errors you get tend to be different and it is a little easier to debug the console host.
If this isn't the problem, feel free to post the code you are using to run the workflow and raise the event.
Matt
kschenk
Hi there,
I have the same problem I have followed the procedure to add the service to the ExternalDataExchangeService too but this has'nt worked .
Also i'm using an ASP.Net application ,'HttpWebHostingModule' and a 'ManualWorkflowScheduler' but am not able to raise events on the workflow.
A stateInitialization activity in the Initial workflow state gets executed though.
Am I still missing somethiong here.....kindly throw some much needed "daylight"
...
Thanks,
crp
Chan65
When you register your local service do you do it the new Beta2 way, or are you still registering the old way
The old way was to call AddService on the workflow runtime and add your local service. The new way is to create an instance of the ExternalDataExchangeService and add that to the runtime. Then, add your local service to the ExternalDataExchange service. This will add it to the runtime for you and does a bit more. I have seen event handlers not get hooked up if you don't use this method.
Matt
Marcin Okraska
Hi Matt,
this is the code written in various layers.
UI is a Web Page:
private
WorkflowRuntime runtime = null; private Guid id = default(Guid); private AutomobileService.AutomobileService automobileService = null; private ManualWorkflowSchedulerService manualservice = null;protected
void Page_Load(object sender, EventArgs e){
id =
Guid.NewGuid(); //Starting the Runtime.runtime =
WorkflowWebRequestContext.Current.WorkflowRuntime; //Creating the Local Service.automobileService =
new AutomobileService.AutomobileService(); ExternalDataExchangeService externalDataExService = new ExternalDataExchangeService();runtime.AddService(externalDataExService);
externalDataExService.AddService(automobileService);
}
protected
void btnSave_Click(object sender, EventArgs e){
if (ValidateControls()){
//Creating an Vehicle ObjectAutomobileObject.
Vehicle newVehicleInstance = new AutomobileObject.Vehicle();newVehicleInstance.VehicleNumber = txtVehicleNumber.Text.Trim();
newVehicleInstance.Damaged =
Convert.ToBoolean(dropDamaged.SelectedItem.ToString());newVehicleInstance.Discount =
Convert.ToDecimal(txtDiscount.Text.ToString());newVehicleInstance.Price =
Convert.ToDecimal(txtPrice.Text.ToString());newVehicleInstance.Shade = (AutomobileObject.
Color)(dropColor.SelectedIndex);newVehicleInstance.TypeOfVehicle = (AutomobileObject.
Type)(dropColor.SelectedIndex);newVehicleInstance.YOM =
Convert.ToInt32(dropYOM.SelectedItem.ToString()); Dictionary<string,object> parameter = new Dictionary<string,object>();parameter.Add(
"VehicleInstance",((object)newVehicleInstance));runtime.CreateWorkflow(
typeof(AUTOWF.AutomobileProcessingWorkflow), parameter, id).Start();runtime.GetService<
ManualWorkflowSchedulerService>().RunWorkflow(id);manualservice.RunWorkflow(id);
//Create a new 'Vehicle'.automobileService.RaiseNewOrder(id, newVehicleInstance.VehicleNumber);
}
}
Local Service
///////////////AutomobileLocalService////////////////////////////////////////////////////////////////////////////////////////////////////
[
Serializable] public class AutomobileEventArgs : ExternalDataEventArgs{
private string strCarNumber; public AutomobileEventArgs(System.Guid guid, string strCarNo):
base(guid){
strCarNumber = strCarNo;
}
public string CarNo{
get{
return strCarNumber;}
set{
strCarNumber =
value;}
}
}
//end of class 'AutoEventArgs'.[
ExternalDataExchange] public interface IAutomobileService{
event EventHandler<AutomobileEventArgs> New; event EventHandler<AutomobileEventArgs> Deleted;}
//end of interface IAutomobileService.
//////////////////////////////////////Implementing the Interface///////////////////////////////////////////////////////////////////
public
class AutomobileService : IAutomobileService{
public AutomobileService(){
}
public void RaiseNewOrder(Guid guid, string carNo){
if (New != null){
New(
null, new AutomobileEventArgs(guid, carNo));}
}
public void RaiseDeleted(Guid guid, string carNo){
if (Deleted != null){
Deleted(
null, new AutomobileEventArgs(guid, carNo));}
}
#region
IAutomobileService Members public event EventHandler<AutomobileEventArgs> New; public event EventHandler<AutomobileEventArgs> Deleted;#endregion
/////////////////////////////////////////////Workflow///////////////////////////////////////////////////////////////////////////////////////
Its a code seperated state m/c workflow and has only two states 'Created(Initial state)' and 'Deleted'
Thanks.......