index > Windows Workflow Foundation > WorkflowStarted event executes twice in an ASP.Net hosted applica...

WorkflowStarted event executes twice in an ASP.Net hosted applica...

Hi,

I have searched the forum for answers to this question, but was unable to find it. I apologise in advance if this has already been answered somewhere...

The problem I am experiencing at the moment is that when I raise the WorkflowStarted event in my ASP.Net page it executes twice. I have investigated this in both Sequential and State Machine workflows. I have also tried running the page in debug and non debug mode, and the same behaviour occurs.

What is happening is that when the WorkflowInstance start method is called, the WorkflowStarted event executes once, and then immediately executes again, once the second execute has completed control is returned back to the calling routine.

If anyone has experienced this issue and found a solution to it then your help will be greatly appreciated.

Thanks

Steve

Please find a snippet of the code below that I have written in my ASP.Net page (The workflow runtime is started in the Global.asax file).

protected void Page_Load(object sender, EventArgs e)

{

ASP.global_asax.workflowRuntime.WorkflowStarted += new EventHandler<WorkflowEventArgs>(WorkflowRuntime_WorkflowStarted);

ASP.global_asax.workflowRuntime.WorkflowTerminated += new EventHandler<WorkflowTerminatedEventArgs>(WorkflowRuntime_WorkflowTerminated);

ASP.global_asax.workflowRuntime.WorkflowCompleted += new EventHandler<WorkflowCompletedEventArgs>(WorkflowRuntime_WorkflowCompleted);

if (!Page.IsPostBack)

{

SqlWorkflowPersistenceService sqlPersistence = ASP.global_asax.workflowRuntime.GetService<SqlWorkflowPersistenceService>();

}

ASP.global_asax._RequestService = ASP.global_asax.workflowRuntime.GetService<RequestLocalServices.RequestService>();

if (ASP.global_asax._RequestService == null)

{

ExternalDataExchangeService dataService = ASP.global_asax.workflowRuntime.GetService<ExternalDataExchangeService>();

ASP.global_asax._RequestService = new RequestLocalServices.RequestService();

dataService.AddService(ASP.global_asax._RequestService);

}

}

void WorkflowRuntime_WorkflowStarted(object sender, WorkflowEventArgs e)

{

//Just some dummy code

int i=1+1;

}

//UpdateGridViewItem(e.WorkflowInstance,"","Completed");

}

protected void BtnClick_Click(object sender, EventArgs e)

{

Button currentButton = sender as Button;

ManualWorkflowSchedulerService scheduler = ASP.global_asax.workflowRuntime.GetService<ManualWorkflowSchedulerService>();

Guid workflowInstanceId = Guid.Empty;

if (Session["WorkflowInstanceID"] != null) workflowInstanceId = new Guid(Session["WorkflowInstanceID"].ToString());

if (currentButton.ID == this.ButtonCreateRequest.ID)

{

int requestId = int.Parse(this.TextBoxRequestID.Text);

// Start the Order Workflow

workflowInstanceId = this.StartWorkflow(requestId);

Session["WorkflowInstanceID"] = workflowInstanceId;

Session["RequestID"] = requestId;

// Raise an RequestCreated event using the Request Service

ASP.global_asax._RequestService.RaiseRequestCreatedEvent(requestId, workflowInstanceId);

scheduler.RunWorkflow(workflowInstanceId);

}

private System.Guid StartWorkflow(int requestId)

{

ManualWorkflowSchedulerService scheduler =

ASP.global_asax.workflowRuntime.GetService<ManualWorkflowSchedulerService>();

// Create a new GUID for the WorkflowInstanceId

System.Guid WorkflowInstanceId = System.Guid.NewGuid();

WorkflowInstance instance = ASP.global_asax.workflowRuntime.CreateWorkflow(typeof(OrderWorkflows.AbsenceRequest), null, WorkflowInstanceId);

instance.Start();

scheduler.RunWorkflow(WorkflowInstanceId);

// Return the WorkflowInstanceId

return WorkflowInstanceId;

}

Steve Dye

Looks like you're subscribing to the WorkflowStarted event twice? Correctly me if I'm wrong but if you make a request for the page you'll subscribe to the event and then when the page is submitted via the button click you'll subscribe again because Page_Load will run again and the subscription isn't in the (!Page.IsPostBack) branch. You'll get called once for each subscription you add...

Thanks,
Joel West
MSFTE - SDE in WF runtime and hosting

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

Joel West
The ideal solution is to subscribe to the runtime events once (per application life time) when you create your runtime in the Global.asax file.


Khalid Aggag - MSFT
Khalid Aggag - MSFT

Thanks for the quick responses guys! Wrapping the event subscription in a not IsPostback has worked. For some reason I thought if you had to subscribe to events across postbacks then the event subscription was not persisted, but I guess as I have declared my workflow runtime instance at Application level then the event subscription will be persisted across postbacks?

Thanks again anyway, I can now move on the next step of my application!

Steve

Steve Dye

Hi, I have run into another issue which I am unsure of how to fix which relates the problem I had earlier.

My theory about the events being persisted as the workflowruntime is declared at the application level has proved to be correct.

So while having an Ispostback fixes this issue when loading the page for the first time (at application start). Subsequent requests of the page (i.e. not a postback) cause the events to be resubscribed to.

Is there a way that I can check if an event has a delegate, or do I have to explicitly remove the event, and then add it again?

Thanks

Steve

Steve Dye

I think that having the event handler on a specific aspx page might be a little bit of a design problem. What happens when you write a different aspx page that also starts a workflow and needs event notification? What do you need to do in this event handler? We'll be able to give some better guidance if you can outline the scenario you want to achieve.

Thanks,
Joel West
MSFTE - SDE in WF runtime and hosting

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

Joel West
As Joel said, adding event handlers in the aspx page itself may be a bit error prone. If you really need that scenario, (as opposed to having one single centralized static event handler added on the Application_Start event), what I would suggest is you filter the events you are interested in via the workflow GUID that come with the "WorkflowEventArgs" in the event (since you may get many events), each page should be interested only in the workflow with the GUID that it started the rest should be ignored, also it would be good to immediately unsubscribe from the event notification once you complete the workflow.


Khalid Aggag - MSFT
Khalid Aggag - MSFT
reply 7

You can use google to search for other answers

 

More Articles

• Workflows vs. ThreadPool
• DelayAvtivity in whileActivity
• xbox live mic help
• Avalon.NET - WWF Runtime and AppDomains
• Error when trying to open the worflow designer --- Beta 2
• What happens to System.Collections.Specialied.StringDictionary?
• Event Sink question
• How to load rules for xoml only state machine workflow?
• Find Dynamically Added Activity
• Custom args class in event from custom activity?
Bookmark and Share
Welcome to Bokebb   New Update  
 

New Articles

• dinamic SQL Server Database Activity con
• Where is the documentation
• Activity Status in Custom Activities
• Host a statemachine and have multiple cl
• add custom activity to workflowdesignerc
• Rehosting Workflow designer (end zoom mo
• workflow compilation
• Threading question again.
• No SqlTimerService ??
• Clarification on persistence & workf
• EventSink ... Where it is?
• Modifyable code in Custom Activity
• difference between state machine and seq
• Activity.DesignMode true when initializi
• SqlWorkflowPersistenceService requires s

Hot Articles

• Require WF Webcasts Power Point Presenta
• Custom Activity Property
• Synchronized "raise event" for
• Calling into an instance through a web s
• Execute an Activity based on Rule evalua
• Events not reaching Workflow...
• BPEL conversion
• Asp.Net Hosted Workflows - Best Practice
• Code samples for Workflow Designer hoste
• WorkflowSubscriptionService - what is it?
• WWF Beta 2 install problem (again) - Pac
• Timers in a Workflow hosted in ASP.Net
• Activities operating on shared data
• Cannot create more than one WorkflowRunt
• [CorrelationProvider]

Recommend Articles

• Behaviour of existing instances in updat
• Saving Activities with a specific Format
• Database monitor activity???
• Adding a Task to Outlook from a work flow
• Dynamically load policyActivity ruleSet
• Installation Issue
• Passing Parameters Problem
• State Machine Web Service
• Using WebService Activities in a Composi
• Changing DependencyProperty at Runtime
• Designtime changed values (by code)
• Where do I find the build script for sta
• FileWatcher sample - Compilation error w
• Calling External method on Exception
• WF instance persistence