How to configure WCF ServiceHost in a Windows service that can access status information in a Windows service

I have a written Windows service in C #. It functions and works well. I added the WCF service to the Windows service so that client applications can connect to the Windows service and receive status information using the Windows service.

I configured the WCF service as a single one, so the same service instance is used to process all requests from all clients as follows: [ServiceBehavior (InstanceContextMode = InstanceContextMode.Single)]

All clients can connect and have access to the same status information in the WCF service. However, I come across the following peculiar behavior.

Corrected version:
I am instantiating a WCF contract in my Windows service. Any status information assigned during instance creation is available to all clients that connect to the service.

However, any status information added to a service contract instance later directly from a Windows service (and not clients) is not displayed to clients that connect to this service. This is similar to two options for a service contract: one for the Windows service and one for the clients that connect to the WCF service.

What is the recommended (best) way to instantiate the WCF service and have access to the status information available in the Windows service?

+4
source share
3 answers

I would recommend doing this from the end, keeping my state in a static member, so it doesn't matter if WCF creates a new instance for each call or reuses it. This solves the problem and simplifies the code.

+2
source

Why should the WCF service have status information? Could you save it in the database and access it when necessary?

WCF allows Singleton instances for services, but it is usually not recommended to use this unless you absolutely must. This is usually simpler and scales much better if you can store status information, for example. database table and allow clients to access it using the regular WCF service for each call.

UPDATE:
Ok, another idea: you will always have only one ServiceHost. If you select the instanciation mode for each call (as recommended by all leading experts), ServiceHost will allocate a pool of workflow threads, which will then serve incoming requests.

Why should the WCF service be single? Could you use the "per call" and still receive status information in the NT service?

A request comes in and an instance of your service object is created (a class of service that implements the service interface). How do you access status information in the NT service right now? Could you do this from a newly created instance of the service - when do you really need it?

If you have status information stored in the NT service, you need to make sure that any concurrent access is handled appropriately - it does not depend on whether your WCF service class is single or not.

UPDATE 2:
Using "OperationContext.Current.Host", you can access the ServiceHost that hosts the given instance of the service inside the executable method of the service - not sure if you can access the actual instance of the NT service. But if you create your own descendant ServiceHost, which has the additional property "ListOfClients", you can access this list at any time from any instance of the service.

EXIT YOU: since it is possible that any number of service requests is processed at any given time, reading the list should be thread safe, and updating the list from Windows NT is even more risky and you need to consider these concurrency problems! Block the list if you need to update it, otherwise you will get unpredictable results.

Mark

+2
source

Setting InstanceContextMode.Single will force ServiceHost to create one instance of your service and use it for all calls. But it looks like you would like to build an instance yourself and populate it with a link to some general state. If so, this is called the "well-known instance" pattern and can be accomplished by passing the instance to the ServiceHost construct, for example:

var svc = new MyServiceClass(state); var host = new ServiceHost(svc, new Uri(..), ...); ... 

ServiceHost will use the instance you pass for all calls.

An important consideration when using Single instance mode (whether the object is โ€œwell knownโ€ or constructed by ServiceHost) is streaming. By default, WCF only allows one thread to run for each instance of the service at a time . Therefore, in PerCall instance mode, since you will have multiple instances of the service, you can support multiple simultaneous streams, which will improve throughput under normal conditions. But in Single instance mode, you only have one instance of the service, so you will only start one thread at a time. It depends on the service, but it often makes sense to switch concurrency mode to Multiple, which will allow multiple parallel threads in your service instance, but requires that your service implementation be thread safe.

Some good docs here: http://msdn.microsoft.com/en-us/library/ms731193.aspx

+1
source

All Articles