PerCall InstanceContextMode behaviour of WCF service - c#

I have a WCF service, exposing a ServiceContract with basicHttpBinding, so from my understanding InstanceContextMode will be set to PerCall (as basicHttpBinding doesn't support sessions) and ConcurrenyMode will be set to Single.
The client of this WCF is a windows service, which invokes 4 different operations on the service at the same time, within the service we have used a singleton class and there are few Static variables. We have been facing a problem where in a wrong value is getting passed to some of the DB Stored Procedures.
With PerCall InstanceContextMode and Single concurrency mode, i understand a new service instacne in created for every call and hence i am thinking that even though there are some singleton classes (we have not made it thread safe) in the service implementation and static variables all the objects will be destroyed, but we have observed running a SQL profiler that on old value is getting passed the DB.
We have written our WCF service code in a kind of 3-tier architecture, i mean ServiceClass, BusinessLogicLayer and DataAccessLayer, with PerCall set as instanceContextMode when we say the service instance is destroyed after the client request is finished, does it mean we destroy all the object in ServiceClass,BusinessLogicLayer and DataAccessLayer?
Pls help me understand what could be going wrong

The InstanceContextMode PerCall means a new class of your service is instantiated per call. Static variables in your AppDomain will not be reset. They will stay between service calls, as long as your AppPool is not recycled.
Remove all statics including singletons from your code. They never belonged to your architecture anyway.

Many WCF requests share the same AppDomain. Static variables are per AppDomain. WCF does nothing to those variables (in fact it cannot even find out they exist). You are responsible for maintaining them.
WCF does not destroy any of your objects because neither does WCF understand what they mean nor does it know they exist.
The settings you mentioned are only relevant to the service object.
My usual advice regarding stateful server apps: You are working under bad practices here. You need to ensure thread-safety. In case the worker process shuts down (deployment, automatic restart, server reboot, app bug crashing the process, power loss, hardware failure, ...) your data is lost.

Though it is restricted in any way static variables needs to be protected for thread safe as a best practice. Static variables will not be destroyed till the service is stopped / app pool recycle.
Using static variables for the data which changes are not recommended for distributed web farms, because those are not safer over a failover.
Visual Studio 2012 and above comes with a Memory profiler. But the simple thing can be done using a counter in the object constructors (only on testing) which can tell if there is a new instance created on every request or not.
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall,ConcurrencyMode=ConcurrencyMode.Single)]
public class TestServiceWithStaticVars : ITestServiceWithStaticVars
{
static int instanceCount = 0;
public TestServiceWithStaticVars()
{
Interlocked.Decrement(ref instanceCount);
}
public string GetInstanceCount()
{
return string.Format("You have created {0} instance", instanceCount);
}
Let you know if better instance counter available to use with ease.
[Edit] as I can't comment now.
Re-assigning the static variable will take the new value as you said. The static variables are loaded in to HighFrequencyHeap for frequent access. For more information http://www.codeproject.com/Articles/15269/Static-Keyword-Demystified

Related

Should C# ClientWebSocket be declared static or instance?

I am currently creating a .NET6 C# trading API client application and the API has two different WebSocket endpoints.
I'm wondering whether the ClientWebSocket object (System.Net.WebSockets) should be declared static or instance. I'm aware HttpClient should be declared static to prevent unnecessary new connections so I'm wondering if the same rationale applies to ClientWebSocket.
From my testing so far my impression is that the ClientWebSocket should be connected and disconnected manually as required, opposed to leaving it connected without any requirement (i.e. just pinging and ponging), and therefore instance objects may be fine to use. Put another way: if websocket connections are explicitly managed there does not appear to be an issue of 'connection re-use' like HttpClient and therefore instances are ok.
Having said that, another design option might be to declare the ClientWebSocket as static and just maintain an open connection + auto re-connect as long as the application is running.
My current design is to have two instance objects of ClientWebSocket, one for each API endpoint. They will be newed up each time a connection is needed.
Any thoughts appreciated.

WCF Call, slow on Internal Funcions, but quick when calling functions directly

I have a self hosted WCF service, using basic http binding. I am finding that calls made to the wcf service, accessing functions exposed by the WCF, take much much longer to complete (internally) than when using the functions directly (from the wcf service).
So to clarify, I am not talking about taking longer "over" the wcf call. Once the internal exposed functions behind the WCF are run, they, in their own processing, take much longer to do their work and return something back to the wcf service, for sending to the client, than when I access those same functions directly from a form in my hosted wcf app.
I have added extensive logging, logging start and stop time for all functions, and it seems to be consistent. The same functions, when activated through WCF, seems as if they are run at a much lower "priority" than when calling them bypassing the WCF interface.
Taking this into account, I am pretty sure this started sticking its head out after I decorated my main wcf class with the following, due to my UI thread locking up:
<ServiceBehavior(useSynchronizationContext:=False)>
Are the threads created due to the above decoration, running at a lower priority?
Direct Call from form in WCF hosted App: 5 seconds
Call Through WCF Interface: 20-30 seconds (Excluding time over the wire)
The physical return from the WCF service itself, once the internal functions are complete, is quite quick.
I do quite a lot of "work" once the internal functions are reached.
Any ideas?
Thanks
Basic WCF Service Code:
Dim myservicehost As ServiceHost
Dim myServiceAddress As New Uri("http://" & LocalIpAddress & ":" & tcp_port & "/" & servicename)
myservicehost = New ServiceHost(GetType(myWCFFunctions), myServiceAddress)
' Enable metadata publishing.
Dim smb As New ServiceMetadataBehavior()
smb.HttpGetEnabled = True
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15
myservicehost.Description.Behaviors.Add(smb)
myservicehost.Open()
I could not get this solved, and reverted back to my previous implementation.

How to check if a WCF service is available?

Can I use Proxy.Open() as an indication to whether the connection should work or not?
I would like to check if a connection is available first, and then, if its not, i won't make any calls to the service during the run of the application.
Note: I only need to check connectivity, not necessarily and entire client-service round-trip.
I Ended up creating a Ping() methods in the service as suggested.
FYI, using simply Open() just didn't work - Open() doesn't raise any exceptions even if the service is offline!
Given the fact that there are so many variables which influence success of a WCF Service call, I tend to add a dummy void KnockKnock()) method to the services to have a real proof if the connection works.
This method can also serve a double purpose: You can call it async to notify the server that he has to be prepared for incoming requests. (Just the initial start-up of the service may take some time.) By invoking the KnockKnock() method the server can start loading the service and give your clients a better initial response performance.

How to persist a webservice reference instance in an SQLCLR stored procedure?

At the moment I have a windows service written in C# that waits for a message in SQL Server Service Broker, and upon receipt calls a webservice method with details passed in the message.
I want to replace this with an SQLCLR stored procedure that calls the webservice directly, which I've found to be quite simple. I can then call this using internal activation.
However it needs to create a new instance of the webservice for each method, and from experience I've found this takes some time. In the windows service I create it with lazy instantiation in a static class, but I understand static fields can't be used to store information in SQLCLR.
Is there a way to persist this webservice reference?
Edit: Here is the lazy instantation code referencing the singleton I'd like to persist:
static class WsSingleton
{
static MWs.MWS mWS = null;
public static MWs.MWS GetMWS()
{
if (mWS == null)
{
mWS = new MWs.MWS();
mWS.Credentials = new System.Net.NetworkCredential("user", "password", "domain");
}
return mWS;
}
}
it needs to create a new instance of the webservice for each method
Do you mean the client has to instantiate a proxy for each HTTP call it makes? If that's what you mean you shouldn't have to persist any reference. An internal activated procedure is launched when there are messages to process and it can stay active and running. Such a locl state could be the proxy instance used to place the WWW calls. Typically the procedure runs a loop and keeps state on the stack as local variables of loop method. See Writing Service Broker Procedures for more details. To be more precise, your code should not RECEIVE one message at a time, but a set of messages.
But I would advise against doing what you're doing. First and foremost, making HTTP calls from SQLCLR is a bad idea. Doing any sort of blocking in SQLCLR is bad, and doing blocking on waiting for bits to respond from the intertubez is particularly bad. The internal SQL Server resources, specially workers, are far too valuable and few to waste them waiting for some WWW service to respond. I would advise keeping things like they are now, namely have hte HTTP call occur from an external process.
A second comment I have is that you may be better of using a table as a queue. See Using tables as Queues. One typical problem with queueing HTTP calls is that the WWW is very unreliable and you have to account for timeouts and retries. Using a table as a quueu can achieve this easier than a true Service Broker Queue. With SSB you'd have to rely on conversation timers for reliable retries, and it makes your activation logic significantly more complicated.

Can an WCF Service create his own host?

I have a client / server type of application and I'd like the server object to create his own host. It looks something like this:
public class Server : IServer {
private ServiceHost m_Host;
public Server() {
m_Host = new ServiceHost(this);
m_Host.Open();
}
}
It seems to work fine when there are few message transfers occurring. But when it starts to speed up (my application requires that data is transfered every 50 ms), the server hangs and and the transfers stop after a few seconds without throwing an exception.
So, is it possible for an object to create his own host? Or do I really have to create it in the main() or do something else?
EDIT: I think the problem in this case is that I want the object that implements the service itself to create his own ServiceHost.
There's nothing really stopping any object to create an instance of ServiceHost.
The big question then is - can you guarantee that your object containing the service host is "alive"? Or was it garbage collected by any chance?
We use Windows (NT) Services to host our own custom service host classes to provide around-the-clock availability for WCF services - works just fine.
Marc
To be a WCF service it simply needs to implement the service contract. There's nothing to stop you adding more methods to open and close an instance of itself as a service.
Check out the ServiceBehaviorAttribute which allows you to specify how your service ... behaves. ;) The ConcurrencyMode property defined the support for multithreading and defaults to single threaded mode, and the InstanceContextMode defines if the service object is per session, per call or singleton.
Quote from ConcurrencyMode:
Setting ConcurrencyMode to Single instructs the system to restrict instances of the service to one thread of execution at a time, which frees you from dealing with threading issues. A value of Multiple means that service objects can be executed by multiple threads at any one time. In this case, you must ensure thread safety.
Quote from InstanceContextMode:
If the InstanceContextMode value is set to Single the result is that your service can only process one message at a time unless you also set the ConcurrencyMode value to Multiple.
We could really use some code examples of your service to further debug the behavior you're describing. For example, is your service object expensive to construct (assuming non singleton implementation), or do the operation slow down? Do you know where the time is spent, is it code, or could it as well be some firewall that limits connection? What protocol do you use?

Categories

Resources