Initialize expensive resource at start up of WCF service hosted in IIS - wcf

I have a WCF service which need to initialize some expensive resources used for all incoming calls. Firstly I used a static variable to record its status, but the variable was reset on every call. Then I used a static service constuctor to init, but it got called on every incoming call. I tried to set InstanceContextMode to Single and PerSession, but neither of them worked.
Any ideas?

Setting your InstanceContextMode to Single is definitely the way to go if you need access to these resources across ALL calls to the service. What probably happened (just a guess) is your worker process is getting recycled, resulting in your initialization code have to run again when a new worker process is started. If that is what is happening, then take a look at this document to configure your application pool to use auto-start.
http://msdn.microsoft.com/en-us/library/ee677260.aspx
If this doesn't help then some additional details on how/where your initialization code is implemented would be helpful.

Related

What are the differences between BackgroundServices and SingletonServices?

I have a service which should begin when the server starts, and continue running for the entirety of the server lifetime. I would like to be able to manage the service (querying, modifying runtime options, etc) with a web frontend. While researching the best way to accomplish this, I came across two options: a scoped service with a singleton lifetime, and a backgroundservice/IHostedService. What are the differences between the two options, and when should one be used over the other?
Neither of those is actually a thing. The closest is the concept of a singleton and hosted services. A hosted service is a class that implements IHostedService and pretty much fits the bill of what you're looking for in that it will start at app startup and stop at app shutdown. ASP.NET Core 3.0 added a BackgroundService class, which is just an implementation of IHostedService with a lot of the cruft of defining what happens as start/stop/etc. covered. In practice, it usually makes more sense to inherit from BackgroundService, but you can also just implement IHostedService directly yourself.
"Singleton" is just a lifetime. All hosted services are registered with a singleton lifetime, but just because something is a singleton, doesn't mean it does anything special. You could, for example, register some random class as a singleton, and whenever it is injected, you'll always get the same instance. However, it will not do anything at startup or shutdown on its own.
Long and short, there are no differing options here. You're looking for a hosted service. That said, it only solves part of what you're looking for, in that it will "run" while the app is running. However, you can't really connect to it, or interact with it directly. It's not like a Web Api or something; it isn't exposed for HTTP requests, for example.
To "manage" it, you would have to expose some sort of API that would then interact with the service through code. For example, the docs provide an example of a queued background service that processes things added to the queue. However, to queue something, you would need to do something like create an API endpoint, inject the queue, and then use code to add a new item to the queue. Then, the actual hosted service would eventually pop that task from the queue and work on it.

Suggestion required to achieve caching functionality in WCF

I’ve a WCF service which is used to get some data from my database. Size of database is very large approximately 2 GB. So I cache this data. I want when service host this data should be cached so I firstly used
InstanceContextMode = InstanceContextMode.Single
This Service Behviors allows me that I can simply write caching code in service constructor, as constructor will only be invoked when servicehost.open (); method call. Whenever client will call this service through proxy constructor will not invoked. This works very fine. Later I realized that this InstanceContextMode has performance issue when 1000 users call this service at a time, because only single instance of this service serves the all requests. To get maximum performance I changed my settings to
InstanceContextMode = InstanceContextMode.PerCall
with
ConcurrencyMode = ConcurrencyMode.Multiple
Now I want to get the same caching feature that is when service host data would be cached. Please help me to solve this problem.
Please do let me know either through CustomBehaviors I can achieve this?
Regards,
Rizwan
Combination of InstanceContextMode.PerCall with ConcurrencyMode.Multiple doesn't make sense. PerCall instancing creates new service instance for each request. Multiple concurrency mode allow service instance to handle multiple parallel requests. How can service instance which is created only to handle single request (PerCall) be used to handle parallel requests (Multiple)?
I think the problem which occured by calling your singleton service (I believe that you also used ConcurrencyMode.Multiple) with 1000 concurrent users is simply based on the fact that server doesn't have performance to deal with so many concurrent users or the service code / caching is not optimized. This will not be solved by using PerCall instancing.
Anyway if you want to share some cache among multiple PerCall instances of the service you have to create some well known object representing your cache - use singleton pattern or service locator. This object will handle caching and concurrent access from service instances.

WCF Named Pipe IPC

I have been trying to get up to speed on Named Pipes this week. The task I am trying to solve with them is that I have an existing windows service that is acting as a device driver that funnels data from an external device into a database. Now I have to modify this service and add an optional user front end (on the same machine, using a form of IPC) that can monitor the data as it passes between the device and the DB as well as send some commands back to the service.
My initial ideas for the IPC were either named pipes or memory mapped files. So far I have been working through the named pipe idea using WCF Tutorial Basic Interprocess Communication . My idea is to set the Windows service up with an additional thread that implements the WCF NamedPipe Service and use that as a conduit to the internals of my driver.
I have the sample code working, however I can not get my head around 2 issues that I am hoping that someone here can help me with:
In the tutorial the ServiceHost is instantiated with a typeof(StringReverser) rather than by referencing a concrete class. Thus there seems to be no mechanism for the Server to interact with the service itself (between the host.Open() and host.Close() lines). Is it possible to create a link between and pass information between the server and the class that actually implements the service? If so, how?
If I run a single instance of the server and then run multiple instance of the clients, it seems that each client gets a separate instance of the service class. I tried adding some state information to the class implementing the service and it was only retained within the instance of the named pipe. This is possibly related to the first question, but is there anyway to force the named pipes to use the same instance of the class that is implementing the service?
Finally, any thoughts on MMF vs Named Pipes?
Edit - About the solution
As per Tomasr's answer the solution lies in using the correct constructor in order to supply a concrete singleton class that implements the service (ServiceHost Constructor (Object, Uri[])). What I did not appreciate at the time was his reference to ensuring the service class was thread safe. Naively just changing the constructor caused a crash in the server, and that ultimately lead me down the path of understanding InstanceContextMode from this blog entry Instancecontextmode And Concurrencymode. Setting the correct context nicely finished off the solution.
For (1) and (2) the answer is simple: You can ask WCF to use a singleton instance of your service to handle all requests. Mostly all you need to do is use the alternate ServiceHost constructor that takes an Object instance instead of a type.
Notice, however, that you'll be responsible for making your service class thread safe.
As for 3, it really depends a lot on what you need to do, your performance needs, how many clients you expect at the same time, the amount of data you'll be moving and for how long it needs to be available, etc.

WCF Workflow Service single instance correlation

Using visual studio 2010 RC/.Net 4.0
I have a wcf workflow service with three receive activities defined, basically StartProcessing, StopProcessing, and GetProcessingStatus. This is a long running service that continues to poll an external service for data once StartProcessing is called, until StopProcessing is called.
My problem is with figuring out how to use correlation to ensure that all calls into the service call the same instance of the workflow. I am trying to avoid requiring any sort of instance id be required to be passed back in to subsequent calls to the service. In a nutshell, I would like the workflow being executed to be a singleton, and ensure that all receive activities operate on the same instance. How do I go about doing this?
You can correlate on a constant for example. Edit the XPath in query correlation to return the number 1 for example.
I think that what you want is impossible, you need to correlate, WWF does not know how to execute it. If two parallel calls are received they will use the same object with unexpected results.
In wcf it could be possible, you can set a session in the client or you could manage wcf object creation, but in WWF I think you even don't have that options.

How to store/save Timer/Threads instances running in WCF service

I'm trying to make a simple scheduler service that will automatically send emails, etc.
For now I have simple WCF service in which I create an instance of a timer, set a callback and do some work in the callback. Now this part works fine, with the callback being called and the work in it being done as expected.
The issue is I need to make some change to the timer, say change the interval or maybe just stop it.
But I can't seem to figure out a way to store/get the instance of that timer that I created. As each time I create a new proxy and access the service, I get a new instance of the service...
I know I could use a static variable but that kind of makes it a 'singleton' service, and the service host I am using at the current time does not support that...
So how can I get that instance of a timer/thread that I actually created in a previous call? Or am I just going about this the wrong way?
Static isn't all that bad of an idea here. Maybe that static is a dictionary keyed by a Guid and the Guid is returned to the client. Subsequent client calls use the Guid parameter, so new instances of your service lookup the timer using the Guid.