views:

258

answers:

6

Not sure if this is the right terminology, let me explain what I want.

I have a web service that's available on the network - the web service has 1 web method.

What I want is... if the web service is running and performing tasks and another call is made to this web service, I want the 2nd call to fail or pend for a certain period of time then fail. Because only 1 instance of this web service should be called at once.

I was thinking of writing a value to the application object (like in asp.net) but then I have to be very careful to make sure that this value gets updated, in case of any errors, it might not... so this is dangerous, and would leave the web service in a state where no one can get to it.

Is there not a more dynamic way to determine if the web service is getting called or not?

+1  A: 

I dont know much about web services on whether you can configure a web server to only start 1 instance of your web service, but you could try creating a mutex within your web service.

A Mutex is an interprocess synchronization object which can be used to detect if another instance of your web service is running.

So, what you can do is create a mutex with a name, then Wait on it. If more than 1 instance of your web service is alive, then the mutex will wait.

Andrew Keith
I really like the sound of this, can you provide more info or a link.
JL
http://en.wikipedia.org/wiki/Mutual_exclusionandhttp://msdn.microsoft.com/en-us/library/system.threading.mutex.aspx
Andrew Keith
@Andew have you personally tried using a mutex with v2 of the .net framework?
JL
I have with some of my applications. I havent tried it in a web service before, but i dont expect it to be different. The .NET mutex is just a wrapper for the win32 API mutex, so it should just work. I have some applications which must behave like singletons as well. So what i do is , when startup, i create a mutex to detect if the user started this application before. Then i just find the window of the previous instance and push it to the foreground. All my apps run on windows.
Andrew Keith
+1  A: 

You could implement the check inside of the webmethod since it will be running in the same IIS process

tster
+2  A: 

If you are using WCF, this is simple. Use the service throttling settings to specify that you want MaxConcurrentCalls = 1 and MaxInstances = 1. You'll also want to set the ConcurrencyMode to Single for your ServiceBehavior.

bobbymcr
+1 on the maxconcurrentcalls and maxinstances = 1 - that's the way to go.I do not recommend using ConcurrencyMode.Single, however - those Singletons have their share of problems, and with this service throttling in place, there's really no need for that anymore.
marc_s
Are you referring to InstanceContextMode.Single?
bobbymcr
+1  A: 

You could create a poor man's mutex and have the first instance create a file and have consecutive instances check the existence of the file. Try Catch your web method and place the deletion of the file in the finally.

Tim Santeford
lol a poor mans mutex, I guess also will need to have the file delete on application startup, in case of server crash, if I go this route.
JL
+1  A: 

You cannot do this with legacy ASMX web services. They have no support for different instance schemes.

I believe you can do this with WCF, as you can configure the service to have only a single instance.

John Saunders
I am using classic, legacy. What are my options?
JL
None, really. My recommendation, frankly, is to "get over it" and "grow up", and start using WCF (it's only been out there for three years, after all). Otherwise you're deferring the inevitable and wasting your time reinventing the wheel. You can imagine how often this recommendation is accepted.
John Saunders
mutex ? I have been using mutex for years. Seems to be reliable and is available in every language since its win32 api. System.threading has a mutex class.
Andrew Keith
Yup good point, you know what... here is the reality, sad but true. I'm using v2, because the idea is the solution can be ported to Mono. But... sincerely I know that it would require a crazy amount of refactoring for my code (full v2 and good code) to port to Mono. So the Mono Port ( which will more than likely never take place) is really just there for management reassurance, really hinders my project and development, done the whole thing this far without any Linq, and MFC... do you feel my pain brother :)
JL
@John, I guess the only other question is - how much effort is required in converting a asmx to an mfc?
JL
@JL: It's WCF (with a .svc extension, maybe), not MFC. BTW, "Mono port" is the first "good reason" I've heard to not use WCF. If your service is well-written, then the port isn't much work at all. See http://msdn.microsoft.com/en-us/library/aa738697.aspx
John Saunders
@John made the port - happy as a lark :)
JL
@JL: Really? You ported from ASMX to WCF? That's great! If you blog about that somewhere, please post the link here.
John Saunders
A: 

If you are WCF I recommend "bobbymcr" answer, but for legacy web service you can use Monitor instead or mutex as mutex is costly (because it is a kernel object) but if you do not care about performance and responsiveness of the service use the Mutex simply.

See this sample for using Monitor class

private static object lockObject = new object();

public void SingleMethod()
{
try
{
Monitor.TryEnter(lockObject,millisecondsTimeout);
//method code
}
catch
{
}
finally
{
Monitor.Exit(lockObject);
}

}
Ahmed Said