How to initialize WCF service before first request occurs? - c#

I have a WCF service that uses various config parameters that are located in a database, as well as a cache for better performance. Right now I have a Singleton that holds this information and is initialized on the first call to the Webservice in a lazy loading behavior.
The cache was exenteded lately and so the initialization takes some time, of course resulting in a longer response time on the first service request.
So what would be the most efficient way to do some kind of eager loading initialization of the service before the fist call occurs (probably on application pool start)?

Don't host the service in an asp.net application, but use a self-hosting process (i.e. a console application) or (even better) a WAS (Windows Activation Service) service within IIS.
This is much more reliable and you can initialize service BEFORE first clien call.
See MSDN for details.

Related

WCF initialization slow vs .NET Remoting

I'm trying to migrate a .NEt Remoting app to WCF, right now both services(Remoting and WCF) are living together.
I have one client consuming both of this services at the same time and I noticed that in the very first call to WCF service it takes a little bit longer than the first call to .NET Remoting service.
With .NET Remoting service the first call get response almost immediately.
.NEt Remoting first call response time: less than a second.
WCF first call response time: about 2 seconds.
I know that there is some initialization cost for WCF connection to be opened, but how can I accelerate this WCF channel wakeup time ??
Any hint?
WCF is doing so much more than remoting. There is a cost for this work. Full stop.
Try calling the WCF service before you need it. Consider adding a Heartbeat() or Init() method to the service to trigger the startup process. If the startup is completed by the first call, there should not be a delay for subsequent calls.
If you have the option to host in AppFabric then you could use the Auto-Start Feature which is specifically designed to get the application initialized before the first client call.
Benefits of the Auto-Start Feature
When you enable the auto-start
feature for a service, the service is up and running as soon as the
application that it belongs to is started and before the service
receives the first WCF message from the client. Therefore, the service
processes the first message quickly because it is already initialized.

Implementing a cache in a WCF Service

I have a WCF service that caches certain data and uses it to respond to web requests. To deal with this requirement, I made the service a Singleton (using InstanceContextMode.Single and ConcurrencyMode.Multiple (yes, it's threadsafe)).
I've tried to set the timeout of the service to its maximum using the following binding:
<binding name="WebHttpBinding" receiveTimeout="24.20:31:23.6470000">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="None" />
</security>
</binding>
My problem is that the service instance dies at unpredictable intervals, meaning the first web request to hit will cause the cache to get rebuilt (a very slow process).
Ideally, the cache would rebuild at a set time each day without having to get hit by a web request. I could set the app pool to recycle at a set time, but this still wouldn't resolve the issue of the service not getting instantiated until the first web request. I'd rather not have to make a little scheduled script that sends a request to the service, as that is kind of hacky.
Is there a better strategy for performing caching in a WCF service? What have others done here? Is there a best practice?
There is an MSDN article on Caching Support for WCF Web HTTP Services, an excerpt is quoted below:
The .NET Framework version 4 enables you to use the declarative caching mechanism already available in ASP.NET in your WCF Web HTTP services. This allows you to cache responses from your WCF Web HTTP service operations. When a user sends an HTTP GET to your service that is configured for caching, ASP.NET sends back the cached response and the service method is not called. When the cache expires, the next time a user sends an HTTP GET, your service method is called and the response is once again cached..........
You might also want to look at:
memcached
Windows AppFabric
NCache
Caching Solutions
WCF Caching Solution - Need Advice
Also look at this on Velocity from Microsoft
I have implemented caching at a higher layer inside the webservice.
This way you can decide when to invalidate the cache, and when to deserialize from disk.
To make sure the cache is built before the first webrequest, add some code to global.asax to generate the cache upon load of the web server.
This is much simpler than doing it the "right way"
[OperationContract]
public void GetLargeComplexData();
public GetLargeComplexData()
{
// deserialize last cached data from db or file
...
// Verify the deserialized cache is not invalid
...
// if cache is invalid rebuild
...
//return cached data
...
}
The receiveTimeout isn't going to affect what you're trying to do. You should use AppFabric to keep your service always running. That way, whenever you recycle, AppFabric will automatically warm up your service. Just make sure that your cache gets built when your service is instantiated, not when it's first accessed.
You can use IIS7 application warmup module
http://blogs.iis.net/thomad/archive/2009/10/14/now-available-the-iis-7-5-application-warm-up-module.aspx
An option you can use is to move the cache out of the WCF service and into a dedicated cache service such as Memcached or use Microsoft AppFabric Caching
This allows you to separate the storage of cached data from the WCF service so you have more freedom in your architecture of how the data is managed and accessed.

Persist object in C# .NET Web Service

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.

can't find main static main method in WCF

I created WCF service and faced with a problem. I need to update database periodically, but i couldn't find static method like Main, that whould do it without client interaction. What can i do??? What wold you suggest in such case?
There is no Main method (or similar entry point) in WCF. You need to host your WCF service in another process (such as a Windows service, or IIS or self host) to "activate" it and make it available to other processes.
One of the concepts in WCF is that you write your service code to do the function you need without having to worry about infrastructure and hosting. Once you have written your service logic, you can then decorate and configure your service to expose it to other processes. Using this approach means you can change how your service is exposed to other processes without re-writing the actual service logic - you essentially just change your configuration. Hence, a main entry point is specific to how you choose to host and expose your WCF service to the outside world.
Just Google around for "WCF hosting" and you will find lots of information.
If you don't need to expose your service logic to an external process (which sounds like maybe the case from your question) then maybe you don't need to use WCF and you can just write a plain old Windows Service.
If your wcf service is self hosted then you can do it in your application before publishing the service.
If it is in IIS then there really isn't application_start kind of thing since the host may be created on first request. See WCF application start event

Understanding Asp.net web service

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,

Categories