I want to Dispose of some objects that are created during a WCF service method, but I need to clean them up outside of the scope of the method that created them. When I'm working in ASP.NET, I normally call that code during the Application_EndRequest event.
If the answer is: there is no Application_EndRequest-like event in WCF, how should I go about cleaning up my objects?
You can implement IDisposable for your WCF service. If the service is configured PerSession or PerCall *context mode* dispose method will be called once the channel is closed and the service instance is dropped.
Related
I have a service reference to a WCF service that is hosted by a customer. The service reference has an interface which defines the service contract. I would like to create a service object which implements this interface so that I can add an instance of this to a local Service Host for testing purposes. This way I can fake the data back while still using the same service definition (though making a local endpoint).
The problem I have so far is this: the service only has one method (right now), GetString. The contract auto-generated two methods, GetString and GetStringAsync. It turns out that when I make a service based on an interface, it automatically generates an async method for each of the defined methods. Which means that my new service now has four methods:
GetString
GetStringAsync
GetStringAsync
GetStringAsyncAsync
If you caught that middle section, there are now two GetStringAsyncs, which prevents the service from starting.
Is there a way I can host a service based on a ServiceReference so that I can keep the same interface? If possible, I would like to prevent just duplicating the defined methods of the service reference in a secondary, as then I can just update the definition and the compiler will notify me when there are new things I need to implement. Also if I do that, my client library (which I want to have as much shared code as possible) will have to have two separate service reference instead of just a configurable endpoint and remote host that I can pass into the client constructor.
I have few questions lined up regarding web service,
Why should we close web service proxy class instance?
how should we close web service proxy class instance for asmx web services?
As using statement itself call dispose method at end, What if close function throws exception from dispose method? - So using statement should be used with try catch for traditional asmx web service for better code clean up ?
Thankful if anybody got a chance to stop by and answer.
I need to run some methods before the first call of a wcf service, where do i put those methods? Where is the startup method of a WCF Service?
Obs1: my WCF Service will run on a IIS6.
Obs2: i'm using .net framework 4.0.
One way to do this is to self host your WCF services (as in not in IIS). That way you can run whatever code you want to before spinning up the services.
Another way is to add a static method call in the constructor of each service behavior implementation. That static method call would do a check to make sure that the initialization had been performed. Just make sure to deal with multi-threaded concurrency during this call.
Depending upon life time configuration of your service WCF will either instantiate the service class on every call (singlecall), for each client (session) or just once for every call of every client (singleton).
You can implement IInstanceProvider interface and take control of the instantiation process. This way you can get a chance to call methods on the class before actual wcf call is done.
I am using netTcpBinding and from what I have read, percall instance context is the recommended way to use wcf. However does this mean that I will not be able to use asynchronous duplex callbacks? Because the service objects are destroyed between method calls so there is no way to perform an async callback on the client? Is this correct?
It seems that if I want to use percall for scalibility, I will be stuck with bad responiveness on client machine because as the callbacks cant be asynchronous. Or have I got it all wrong?
You mix up client instances and server instances. InstanceContextMode.PerCall means that every call from a client gets a new object serving that single request.
The callback channel(s) which you are talking about are communicating the other way round: They call methods in your client. Your client should stay alive and is a single instance from the servers point of view.
So all you need to persist on the server side after a method call is the clients operation context. Because thats the reference you need to send a message to your client by using the callback contract.
So as a result, you can use async callbacks with InstanceContextMode.PerCall, but you will have to provide some session state storage by yourself.
What do you mean exactly with asynchronous duplex callbacks?
You can use a normal duplex contract and then make calls to this in an asynchronous way so that the client doesn't block. Obviously the service object need to stay alive until it has called back to the caller.
I have a written a Windows Service in C#. It is functioning and performing well. I have added a WCF service to the Windows service to enable client applications to connect to the Windows service and obtain stateful information from the Windows service.
I configured the WCF service to be a singleton, so that the same service instance is used to handle all requests from all clients as follows:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
All clients are able to connect and have access to the same stateful information within the WCF service. However, I am running into the following peculiar behavior.
Revised:
I instantiate the WCF service contract within my Windows Service. Any stateful information assigned at the time of instantiation is available to all clients that connect to the service.
However, any stateful information added to the service contract instance later directly from the Windows Service (not by clients) is not visible to clients that connect to the service. It is as if there are two instances of the 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 a WCF service and have it be able to access stateful information available within the Windows Service?
I would recommend doing an end-run around this by holding your state in a static member, so that it doesn't matter whether or not WCF is creating a new instance for each call or reusing one. This solves the problem and simplifies the code.
Why does the WCF service have to have stateful information? Couldn't that be stored in a database and accessed when needed?
WCF does allow Singleton instances for services - but it's usually discouraged to use this, unless you absolutely, positively have to. Typically, it's easier and scales much better if you can store the stateful info in e.g. a database table and let clients access that using a normal, per-call WCF service.
UPDATE:
OK, another idea: you'll always only gonna have a single ServiceHost anyway. If you choose the "per-call" instanciation mode (as recommended by all leading experts), the ServiceHost will allocate a thread pool of worker threads which will then service the incoming requests.
Why does the WCF service need to be a singleton? Couldn't you use "per-call" and still get at the stateful information in the NT Service?
A request comes in and an instance of your service object (the service class, implementing the service interface) is created. How do you access the stateful information in the NT service right now? Couldn't you do that from the newly created service instance, too - when you actually need it?
If you have stateful information being held in the NT Service, you'll need to make sure any concurrent access will be properly handled - that's totally independent of whether your WCF service class is a singleton or not.
UPDATE 2:
Using the 'OperationContext.Current.Host', you can access the ServiceHost that hosts a given service instance inside the service method being executed - not sure if you can access the actual NT service instance. But if you create your own custom ServiceHost descendant, which has an additional property "ListOfClients", you should be able to access that list at any time, from any service instance running.
MIND YOU: since there are possibly any number of service requests being processed at any given time, reading the list must be thread-safe, and updating the list from the Windows NT Service is even more "risky" and needs to take these concurrency issues into account! Lock the list if you need to update it - otherwise, you'll have unpredictable results.
Marc
Setting InstanceContextMode.Single will cause the ServiceHost to construct a single instance of your service and use that for all calls. But it sounds like you would like to construct the instance yourself, and populate it with a reference to some shared state. If so, that's called the "well-known instance" pattern and can be accomplished by passing the instance to the ServiceHost constructory, like so:
var svc = new MyServiceClass(state);
var host = new ServiceHost(svc, new Uri(..), ...);
...
ServiceHost will use the instance you pass in for all calls.
An important consideration when using the Single instance mode (whether the object is "well-known" or constructed by the ServiceHost) is threading. By default WCF will only allow one thread to execute concurrently per service instance. So in the PerCall instance mode, since you'll have multiple service instances, you can support multiple concurrent threads which will improve throughput under normal conditions. But with the Single instance mode you only have one service instance so you'd only run one thread at a time. It depends on the service, but it often makes sense then to switch the concurrency mode to Multiple, which will allow multiple concurrent threads into 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