views:

432

answers:

4

I'm working on an integration testing project in .NET. The testing framework executable starts a service and then needs to wait for the service to complete an operation.

What is the best approach for the exe to wait on the service to complete its task (the service itself will not exit upon task completion)?

Both processes have access to the same database, so my first thought was a simple table that records the service's status. Once it's signaled that it's done, the exe can stop waiting and complete its task. Other approaches?

Let me reiterate that the service, once it has completed its task, will remain in a running/in-memory state, so waiting for it to exit won't work. ;-)

Also, this is purely for integration testing purposes, and will never go into production, so "simple" is the operative word.

A: 

You could use IPC Channels: http://articles.techrepublic.com.com/5100-10878_11-6143016.html

Or maybe two way remoting: http://www.codeproject.com/KB/IP/TwoWayRemoting.aspx

The database route would be simple, but not necessarily the best.

Max Schmeling
+1  A: 

WMI calls should give you what you need. You can catch started/finished events and do what you need to from there. (Thanks to Chris Lively for showing me this)

http://weblogs.asp.net/whaggard/archive/2006/02/11/438006.aspx

Alternatively you can use System.Diagnostics.Processes namespace to query for one particular active process, and loop until the process is killed.

Ian Jacobs
WMI... interesting. What would trigger the "processmodified" event?
scottmarlowe
I'm not really sure to be honest, I only leaned about this a couple of days ago. I imagine it would be something along the lines of it's properties changing.
Ian Jacobs
+4  A: 

You can pass a Semaphore name to the service on the command line (or via some other mechanism, like hard coding), and then wait on the service to Release() it, by calling WaitOne() in your exe.

App code:

Semaphore s = new Semaphore(1, 1, "MyNamedSemaphore");
// start service, passing the string "MyNamedSemaphore"
s.WaitOne(); // will wait for Release() in service

Service code:

// perform the initial task
// find semaphore name (i.e. from Environment.CommandLine)
Semaphore s = new Semaphore(1, 1, semaphoreName); // will use existing kernel object
s.Release(); // WaitOne in exe will complete
Lette
awesome. I think this will work perfectly. Thanks!
scottmarlowe
Of course, you may just hard code the semaphore name. Just make sure that it's unique.
Lette
+1  A: 

Can you modify the service code?

If so, use a kernel Event object - the service can create one, your app can wait for it to be signalled, and the service can signal it when its finished. You'll have to give the event a name for it to be used cross-process but that's about as simple as it gets. The service can even continue to run with the event code present, no-one will notice unless they try to create an event with the same name. (or, your testapp could create the event, the service can then try to open it, depending which one is started first. If it succeeds, it can performs its triggering, otherwise it works as usual).

Hint: you want a auto-reset event which 'flips' its state back immediately its triggered all waiting threads.

I'm not sure of the .NET routines, but you want the Win32 CreateEvent, SetEvent, and WaitForSingleObject.

gbjbaanb
yep. coming from a C++ background, I've used those before. The named kernel event was eluding me, though. thanks.
scottmarlowe