When I do not specify InstanceContextMode in the service, what's the default instance mode?
It's PerSession
Link to MSDN doc
The simple answer is that the default Instancing mode is PerSession
Provided:
The Session Type you are using supports sessions
See [Binding type session support] (https://learn.microsoft.com/en-us/dotnet/framework/wcf/system-provided-bindings).
If the channel does not create a session the behavior is as if it were PerCall.
The Service contract allows sessions - default is "Allowed"
Here is a Microsoft provided sample with the default imperatively configured in the code.
Default behavior sample
[ServiceBehavior(
AutomaticSessionShutdown=true,
ConcurrencyMode=ConcurrencyMode.Single,
InstanceContextMode=InstanceContextMode.PerSession,
IncludeExceptionDetailInFaults=false,
UseSynchronizationContext=true,
ValidateMustUnderstand=true)]
public class CalculatorService : ICalculator { ... }
I found reading about session in this Microsoft article ( Using Sessions ) particularly enlightening in understanding how Sessions is opened and closed and how this relates to Instancing and Concurrency.
By default the WCF client will create a new session, which will create a server instance, all calls for the duration of the session is called a conversation and is served by a single instance (Instancing) of the server with a single thread (Concurrency) dedicated to that session/client/conversation.
If you use the default instancing behavior in WCF, all calls between a WCF client object are handled by the same service instance. Therefore, at the application level, you can think of a session as enabling application behavior similar to local call behavior. For example, when you create a local object:
A constructor is called.
All subsequent calls made to the WCF client object reference are processed by the same object instance.
A destructor is called when the object reference is destroyed.
Sessions enable a similar behavior between clients and services as long as the default service instance behavior is used.
Hope this helps someone as it took me a while to find the answer.
Not all bindings support PerSession mode like basicHttpBinding that supports Percall mode by default.
Related
I am reading Juval Löwy's Programming WCF Sevices. It mentions:
In WCF, we have Context in which we have the instance. By default, the lifetime of the context is the same as that of the instance it hosts. We can have separate lifetimes for both.
WCF also allows a context to exist without an associated instance at all.
Why would we release the instance and keep the context empty?
Coincidentally I recently read the chapter you're probably referring to. In his book Löwy explains why this may be useful. First he writes:
WCF also allows a context to exist without an associated instance at all. I call this instance management technique context deactivation.
After mentioning this is typically done using an OperationBehavior with a specific ReleaseInstanceMode, he goes on and hints on when you could use this:
You typically apply instance deactivation on some but not all service methods, or with different values on different methods. [...] The reason you typically apply it sporadically is that if you were to apply it uniformly, you would end up with a per-call-like service, in which case you might as well have configured the service as per-call.
So you can use this "deactivation" to ensure only certain methods in a service with sessions behave as if they were part of a per-call service. The abovementioned MSDN article also explains this, in a different wording:
Use the ReleaseInstanceMode property to specify when WCF recycles a service object in the course of executing a method. The default behavior is to recycle a service object according to the InstanceContextMode value. Setting the ReleaseInstanceMode property changes that default behavior. In transaction scenarios, the ReleaseInstanceMode property is often used to ensure that old data associated with the service object is cleaned up prior to processing a method call.
Disconnecting the context from the instance makes sense when:
Instance creation is customized/extended. For example if you are creating your service instance with a custom IInstanceProvider with a dependency injection library (for example Unity) you might want a Unity lifetime manager to handle the service instance lifetime.
Some but not all operations result in an expensive service instance to be invalidated. For example: The service object loads a large expense resource as a part of creation. If the service operations called by the client modify or invalidate the resource, it needs to be disposed and reloaded for the next caller. If the operations don’t invalidate the resource the service instance can be reused by the next caller. (In almost all cases there’s a better way to solve this problem, but WCF allows it).
I’m sure there are additional use cases.
Hopefully WCF has a reach instancing and concurrency management at service-side via Throttling.
My service client is an ASP.NET application. It consumes more than one WCF service so I create and parametrize WCF client at run-time (no configuration file is used).
Only the end point address is dynamic, and all the services (used by client) have the same method signatures (same contract).
For this reason I have referenced the service through Visual Studio and it has created my service proxy so I just take care of endpoint address at run-time:
class MyWcfClient
{
void DoSomething(string endpintAddress, int data)
{
// Create 'binding' and 'endpoint' ('endpoint' address is dynamic)
ServiceReference.ServiceClient serviceClient = new ServiceReference.ServiceClient(binding, endpoint);
// Parametrize 'serviceClient'
// Call WCF method (send 'data' to appropriate endpoint)
serviceClient.CLose();
}
}
Since the client is an asp.net application, each request runs on it's own worker thread (WCF method calls are very light and fast, so the thread would not block for a long time).
My question is about the instanciation and concurrency at the client-side.
Should MyWcfClient class be Singleton with one serviceClient instance or it be static class and a new serviceClient be created for each call ?
Should I create serviceClient (i.e, an array or list) based on the endpoints (there are 10-100 endpoints) ?
Note that my asp.net threads should not be blocked for a long time (i.e waiting in a queue for sending their related data via WCF)
There is no throttling on client side and it is not needed because you have client code under your control so you have control over number of requests executed. That is the difference to service where without throttling there is no control over number of incomming requests executed elsewhere (out of service control).
So if you want to control number of requests concurrently executed on client you must create object pool - there will be only limited number of MyWcfClient classes available and each class will always create new ServiceClient. Requests will wait in queue for free MyWcfClient instance.
If your only problem is how to create instances of ServiceClient then answer depends on type of binding.
Sessionful bindings like Net.Tcp, Net.Pipe or WsHttp with reliable session or security context: Create new instance for each communication relation. If your relation is just single call, create new instnace for each call. So you can use static class with static method and create new instance in that method.
Sessionless bindings like BasicHttp or WebHttp: You can reuse client for multiple calls but you can't close the client between subsequent calls. You can use array of prepared client instances. You will still need to handle some errors here.
Btw. also check asynchronous client calls and how to correctly close the service client.
I have recently come across the term Instance Deactivation.
a) What is that?
b) What for we need that?
c) In what context will it be useful?
I am looking for a simple answer that can be easily undestandable and if posible with some pseudo code.
Thanks
When a WCF method is invoked, it is passed to a service instance.
Instance Deactivation simply refers to the moment where the WCF system disposes of this instance.
In a Per-Call Service, instance deactivation will occur after each method call.
In a Per-Session Service, instance deactivation will occur when the client calls Close on the proxy, or when the transport-session's inactivity timeout is reached.
In a Singleton Service, instance deactivation will occur when the Service Host is closed.
You can also configure individual service methods to trigger instance deactivation:.
[OperationBehavior(ReleaseInstanceMode = ReleaseInstanceMode.AfterCall)]
public void MyMethodWhichTriggersAnAutomaticRelease()
{
// ...
}
As well as this, you can manually trigger a service instance release:
public void MyMethodWhichTriggersAManualRelease()
{
OperationContext.Current.InstanceContext.ReleaseServiceInstance();
}
Juval Lowy has this to say on whether you should manually override the standard instance deactivation mechanisms:
Instance deactivation is an
optimization technique, and like all
optimization techniques, you should
avoid it in the general case. Consider
using instance deactivation only after
failing to meet both your performance
and scalability goals and when careful
examination and profiling has proven
beyond a doubt that using instance
deactivation will improve the
situation.
Basically I take to mean that the instance of the class that the service operation is being called on is not torn down. If you have per call activation then a new instance of the service class will be created each time you call an operation on the service. After the method ends then that instance of the class will be disposed.
If you want to improve performance say at the expense of scalability then you would not deactivate the instance and thus choose a different instance activation scheme.
This MSDN artice : Discover Mighty Instance Management Techniques For Developing WCF Apps together with the link in #SteveCav answer provide good references.
From a little bit of reading around, it is my understanding that the only way to detect that a client has connected to my service is through writing my own code. I am using a Singleton service. I would like to display a message every time a client connects to my service that client x with ip xxx has connected. There is no built-in event that is generated? Am I correct?
No, I don't think there's any support in WCF for your requirement.
Not sure what you want to achieve with this, either. Your service class (in your case, just a single instance) really doesn't have any business putting up messages (on screen, I presume) - that really not it's job. The service class is used to handle a request and deliver a response - nothing more.
The ServiceHost class might be more of a candidate for this feature - but again, it's job really is to host the service, spin up the WCF runtime etc. - and it's really not a UI component, either.
What you could possibly do is this
have an Admin UI (a Winforms, console, or WPF app) running on your server alongside your service, providing an admin service to call
define a fast connection between the two services (using e.g. netNamedPipe binding which is perfect for intra-application messaging)
when your "real" service gets a call, the first thing it does is send out a message to the admin UI which can then pick up that message and handle it
That way, you could cleanly separate your real service and it's job (to provide that service) and the Admin UI stuff you want to do and build a cleanly separated system.
I have actually implemented my own connect, disconnect and ping service methods which I manually call from my client once the channel has been created. By using them as a kind of header section in all of my ServiceContract interface definitions (and their implementations, of course), they form an makeshift "base service definition" that only requires a bit of cut-n-paste.
The string-based parameters of connect and disconnect will be used to send client info to the server and return server info and (perhaps a unique connection id) to the client. In addition a set of timing reference points may make its way in also.
Note how SessionMode is required and the individual OperationContract properties IsInitiating and IsTerminating are explicitly specified for each method, the end result being what I would call a "single-session" service in that it defines connect and disconnect as the sole session bookends.
Note also that the ping command will be used as the target of a timer-based "heartbeat" call that tests the service connection state and defeats ALL connection timeouts without a single config file :-)
Note also that I haven't determined my fault-handling structure yet which may very well add a method or more and/or require other kinds of changes.
[ServiceContract( SessionMode = SessionMode.Required )]
public interface IRePropDalSvr {
[OperationContract( IsInitiating=true, IsTerminating=false )]
string connect (string pClientInfo);
[OperationContract( IsInitiating=false, IsTerminating=true, IsOneWay=true )]
void disconnect (string pClientInfo);
// ------------------------------------------------------------------------------------------
[OperationContract( IsInitiating=false, IsTerminating=false )]
string ping (string pInp);
// ------------------------------------------------------------------------------------------
// REST OF ServiceContract DEFINITION GOES HERE
One caveat: while I am currently using this code and its implemention in my service classes, I have not verified the code yet.
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.