Can you please answer to the following questions to enlighten me about web services.
What is the lifecycle of web service ? When the class which represents my web service gets instanced and when it's start running (executing) ?
Is it there new instance created for every webMethod call ? And what happens if there are multiple simultaneous requests for same or different web method ?
When to open connection to remote resource, that the onnection is ready before any requests. And this connection must persist through whole lifetime of web service.
Thank you in advace for all answers.
Webservices are nothing more than ASP.NET pages communicating on the SOAP protocol (XML over HTTP). Each method have its own round-trip (like a page, so new instances are created by default). ASP.NET thread pool is used for running a webservice. As web programmer you don't have lot of control over how thread pool is used since it depends on many external factors (system resources, concurrent page requests...).
If you mean database connections by 'Opening connection to remote resources' these connections also are pooled by Connection Pool of ADO.NET and it will be managed automatically. If you external resources are heavy use Singleton webservice model and load external resources in constructor. Don't use singleton patteron on a database connection (It has its own pooling mechanism). You should take care of concurrency issues for your static variables if you are choosing Singleton pattern.
At the end I should say living in managed-world of programming is easier than ever. Most of the time somebody is caring about our doubts.
That depends; You have two instancation models.
"Single Call" (an instance is created for each call made to the service)
"Singleton" (an instance is created on the first call and reused as long as the process remains alive).
See answer 1; Eleboration; Yes, each call get's its own instance
I would seperate that away from the actual Web Service class. You can use another singleton approach to achieve this functionality.
Hope this helps,
Related
What's the general rule of thumb to decide whether to use PerSession or PerCall?
I have a slightly heavy (I think..) WCF service, containing CRUD methods to about 80 tables.
I have separated the WCF service into 7 contracts within 1 service, (i.e., 7 end points within 1 service) such that each contract takes care of its own domain, for example I have a Sales contract, so all sales related tables, and its corresponding operations are within the sales "bounded context"
So my WCF service structure looks something like this:
public partial class ABCService : ISalesService
{
//CRUD methods of all tables related to Sales
}
public partial class ABCService : IMarketingService
{
//CRUD methods of all tables related to Marketing
}
public partial class ABCService : ICustomerService
{
//CRUD methods of all tables related to Customer
}
public partial class ABCService : IProductService
{
//CRUD methods of all tables related to Products
}
My concern with PerCall is that, because I have a fairly large DB/WCF service, I'm afraid that the amount of resources consumed by each call, multiplied by the number of users and the rate of which they call the service, would be far too great.
I do not know the fine details, but I have read that creating a Channel Proxies are expensive operations.
Oh, I'm using hand coded proxies instead of VS's Add service reference to consume my WCF service.
So, my question is, which should I use? PerSession or PerCall?
Update:
I do not need to maintain state between calls.
I'm using NetTCP bindings
In my opinion, to take a decision consider these two points
For going with InstanceContextMode.PerSession - If your users have some session values stored on the WCF service on the server.
For going with InstanceContextMode.PerCall - If your users have nothing stored in session on the WCF service on the server i.e. WCF service requires No per user settings required to store in memory. Requires scalability.
Some points regarding When-And-Why,
InstanceContextMode.PerCall
If your service is stateless and scalable, i.e. benefits are similar to HTTP as it is also stateless.
If service has light-weight initialization code (or none at all).
If your service is single threaded.
Example scenario: For any 1000 client requests in a given time period in a PerCall situation, there will only be 100 objects instantiated for 100 active calls. Secondly if server were to crash then in PerCall situation the only errors that would occur would be to the 100 actual requests that were in progress (assuming fast failover). The other 900 clients could be routed to another server on their next call.
InstanceContextMode.PerSession
If your service has to maintain some state between calls from the same client.
If your service has light-weight initialization code (or none at all). Even though you are only getting a new instance for each client proxy, you still want to be careful about having expensive initialization code in a constructor.
Example scenario: For any 1000 client requests in a given time period in a PerSession situation you may have 1000 objects instantiated on the server but only 100 are actually active in call at any moment. And thus instantiated PerSession objects could be a waste of resources and may impact the ability to serve requests under load. Secondly if server were to crash then in PerSession all 1000 clients who have a session on that server would lose their session and be unable to complete their work.
Reference links:
MSDN - WCF Instancing, Concurrency, and Throttling
SO - Per-Call vs Per-Session
MSDN - Using Sessions in WCF context
The reason you don't see many answers to this type of question online is that it depends. What I would do is try it out -- then open up perfmon on the server where you are hosting the service and add the counters for your service. Just google wcf performance manager counters if you aren't familiar.
The good news is that WCF makes changing the setup pretty easy.
If you are concerned with the cost of instantiating a proxy on the client side, remember that perCall is a service behavior, not a client behavior. Even if you set the service instance context to PerCall, you can still create one instance of your proxy and make a bunch of method calls from that proxy. All perCall means is that when you make a call, an instance of the service is created, your method is called, and the instance of the service is torn down again. If you don't have any expensive initialization on the service instance (i.e. if they're basically static methods) you're probably ok with per call.
Am stuck on what am sure is a fundamental and easy to solve problem in WCF, just need to be guided towards the right way.
I have a large object (which is actually a trained text classifier) that I need to expose through a Web Service in C# .NET. The classifier object can be loaded from disk when the service initially starts, but I don't want to keep loading it from disk for every request (the object that services requests currently occupies about 6 GB in memory, and it takes a while to keep loading it from disk for every request), so instead I want to persist that object in memory throughout all requests to that web service, and the object should only be loaded when the service starts (instead of loading it when the first web request triggers it).
How would I go about doing that?
Thanks for any help!
Probably the easiest way is to create your service as a singleton. This involves specifying InstanceContextMode = InstanceContextMode.Single in a ServiceBehavior attribute on your service class definition.
However it is very questionable if sending a 6GB object over the wire using WCF is advisable. You can run into all sorts of service availability issues with this approach.
Additionally, singletons are not scalable within a host (can be only one instance per host), although you can host multiple singleton services and then load-balance the requests.
The way I've done this in projects that I've had the problem with in the past is to self host the WCF service inside a Windows Service.
I've then set the data storage object up inside the service as a singleton that persists for the life of the service. Each WCF service call then gets the singleton each time it needs to do something with the data.
I would avoid running in IIS simply because you don't have direct control of the service's lifetime and therefore don't have enough control of when things are disposed and instantiated.
I have a web server (ASP.NET - Mono 2.6.7) with a value static float x in it and two methods : getX() and setX(newX). I also have two clients one is a pc with c# console application and the other one is a mobile device with android (ksoap2). Both can access the web server.
What I do not know is : if my mobile device try to do a getX() while my pc is doing a setX(newX), will it result any trouble ?
Thanks.
It's not a good practice to have a state-full implementation for services. You can have different instances serving multiple requests. This is the case in ASP.NET web services. In WCF, using configuration, you can change instancing behavior. For example, you can have a single instance serving all requests (few of them can be concurrent) - in case, one has mutable state (as in your case), you have to synchronize the access to the state. Thread synchronization on shared state will create a bottleneck in serving the requests because at the most only one request thread can access the state. Further, you cannot scale horizontally (i.e. web farm scenario where requests will be served from multiple machines). If you choose to have multiple instances serving the request then you need to externalize the state e.g. put it into the database. In such case, you will incur in the penalty of accessing external data source (which can be much higher than thread synchronization) but you will have scalable design.
Roughly-speaking, a web service class/object should not be stateful in itself. You can store state, but it's usually externally, for example in a database.
This is because, depending on configuration, there's no guarantee that it will be the same instance of the class for every request for every client.
I need to make a thread inside my web service, to check on some data in my database every specific time.
I would not do that. The thread would die with the application pool. Create a windows service which checks the database using a Thread or a Timer.
Why would you want to do that?
If your service is per-call (i.e. not singleton), all the resources involved in servicing a request is supposed to be released right after the call. If you spawn a thread, the request will be kept alive until your thread completes.
Also, checking on data in a database periodically does not really make sense in a web service call, which should complete within a very short time anyway, otherwise you kill scalability.
You're probably referring to a singleton web service, in that one single server object services requests. In this case, you'll need to create the singleton object first -- most likely in a Windows service that is started automatically.
Your database polling is most likely used to cache certain popular values so that servicing requests do not need to hit the database itself. In this case, your service is actually a middle-tier layer. Unless you know that data in the database changes very frequently, consider replacing the database polling with triggers in the database that calls the web service to update new data.
I have a WCF webservice that acts as a data provider for my ASP.NET web page.
Throughout the web page a number of calls are made to the web service via the auto-generated ServiceClient.
Currently I create a new ServiceClient and open it for each request i.e. Get Users, Get Roles, Get Customer list etc.... Each one of these would create a new ServiceClient and open a new connection.
Can I make my ServiceClient class a global or statically available class so that all functions within my ASP.NET web page can use the same client. This would seem to be far more efficient. Are there any issues with doing it this way? Any advice I should take into account when doing this?
What happens if I make multiple requests to a client? Presumably it is all synchronous so it shouldn't matter if I make 1 or 50 calls to it?
Thanks
When session (wsHttp with security context or reliable session) or connection (net.tcp, net.pipe) oriented binding is used you have to handle your proxy in the way you want to handle the session. So if you share the proxy, all calls will be handled in single WCF session (by default handled by single service instance). But you have to deal with additional complexity like: Unhandled service exception will terminate your channel and following call from client will result in exception.
When session-less HTTP binding (basicHttp, webHttp) is used you can share your proxy or even make it static. Each call is handled separately, exception on a service will not fault the channel and it transparently reuses opened HTTP persistent connections. But because of this, there should be no big overhead to creating new proxy / channel.
So my suggestion is: When you need several calls to your service in single request processing in your ASP.NET application, use the same proxy / channel. But don't share proxy / channel among different requests.
I think using a ChannelFactory could take of your problem. If I'm right the ChannelFactory has a pool of your connection and re-uses the channels. The advantage of this is that the channels don't get instatiated each time, only the first.
Read more here: ChannelFactory
To handle the disposing of the channels you need some special handling since the channel can throw exception in dispose. I wrote a mapper to handle this, you can read about it here: http://blog.tomasjansson.com/2010/12/disposible-wcf-client-wrapper/