How can an activity close itself?

This might be a little bit of a na?ve question. I want to have an activity terminate itself after some activity-determined event. As an example, I tried just using a timer (the real code will be looking for other events besides time). I created the following code (as part of an activity) and can’t figure out how to finish up in the MyTimer_Elapsed. I know my example is wrong and can’t work… the ActivityExecutionContext can’t be saved and used later, but I think using it incorrectly shows better what I’m trying to achieve.

Timer MyTimer =null;

ActivityExecutionContext MyContext;

protectedoverrideStatus Execute(ActivityExecutionContext context)

{

MyContext = context;

MyTimer =newTimer(1000);

MyTimer.AutoReset =false;

MyTimer.Elapsed +=newElapsedEventHandler(MyTimer_Elapsed);

MyTimer.Start();

returnStatus.Executing;

}

void MyTimer_Elapsed(object sender,ElapsedEventArgs e)

{

MyContext.CloseActivity();

}

How do I accomplish this? I’m sure the answer is fairly simple…

[5279 byte] By [SteveSampson] at [2007-12-18]
# 1

Hi Steve,

For this simple sample, you would use a Delay activity instead. For a more complex example where you have long running work you would use the InvokeMethod - EventSink activity pair to farm the long running work out to the host.

Regards,
Paul

PaulAndrew at 2007-9-8 > top of Msdn Tech,Software Development for Windows Vista,Windows Workflow Foundation...
# 2

I'm aware that I could have used the Delay activity. Essentially, I think, I'm asking how to implement my own "Delay" activity. I don't see how to do that within the current framework, though I'm sure it is possible. I tried messing around with IEventActivity though I couldn't find any documentation on how to use it. I couldn't create a QueueEventArgs object (the class doesn't have a constructor) so I gave up going down that path.

I think I understand the InvokeMethod/EventSink activity pair but I'll have to do some experiments to see if I really do (I haven't tried it yet) but I'm not sure I like this solution. Maybe I can create a custom sequence activity that does this so it can be packaged as a single activity.

The reason I'm attempting to do something like this is that our existing product allows users to generate their own workflows. We currently use a custom workflow system, but we're looking into whether we want to use Windows Workflow as our new workflow system. I want my activity to appear as a single activity in the workflow rather than requiring that the user always create a more complicated workflow with two activities. (One overriding goal in moving to a new workflow system is to make it easier for our customers to create simple workflows and a two-activity approach does just the opposite. This activity will be an essential activity that nearly all our customers will use.).

Thanks for your responses so far.

Steve

SteveSampson at 2007-9-8 > top of Msdn Tech,Software Development for Windows Vista,Windows Workflow Foundation...
# 3

Steve,

You can implement your own delay-like activity. The problem with the original approach was that a regular windows timer was being used - but what would happen if the workflow unloaded in between? When the windows timer fired, there would be no existing instance to execute. To implement this in a reliable manner, use the timer APIs on ActivityExecutionContext - see "SetTimer" and "CancelTimer". The sender should be the context, which you can use to close the activity.

http://winfx.msdn.microsoft.com/library/en-us/cpref/html/T_System_Workflow_ComponentModel_ActivityExecutionContext_Methods.asp

Hope this helps,

Arjun

ArjunBanker at 2007-9-8 > top of Msdn Tech,Software Development for Windows Vista,Windows Workflow Foundation...
# 4

Hi,

I tried to use the "SetTimer" method from the ActivityExecutionContext like this:

protected override Status Execute(ActivityExecutionContext context)

{

.....

DateTime currentTime = DateTime.Now;

DateTime timerExpiration = currentTime.AddSeconds((double)SecondsTimeout);

context.SetTimer(timerExpiration, new EventHandler<EventArgs>(ActivityTimedout));

... ...

return Status.Executing;

}

However, no matter what large value I set to "SecondsTimeout", the timer handler "ActivityTimedout" is always called by the workflow runtime immediately, resulting in canceling out the activity too soon. Why? The only idea I could think of is that may be I did not register the in-memory timer service to the workflow runtime?

Thanks for any helps,

Jiebo

JieboGuan at 2007-9-8 > top of Msdn Tech,Software Development for Windows Vista,Windows Workflow Foundation...
# 5

I got it work. The problem was in the way I set up the timer. Instead of getting current time using DateTime.Now, which gets the local time, getting current time using DateTime.UtcNow worked.

Jiebo

JieboGuan at 2007-9-8 > top of Msdn Tech,Software Development for Windows Vista,Windows Workflow Foundation...

Software Development for Windows Vista

Site Classified