Problems with singleton pattern inside WCF service method - c#

I will go ahead and preface this by saying: I am somewhat new to WCF.
I'm working on a server-side routine that's responsible for doing a great deal of business logic. It's accessible from a client via WCF.
My main WCF method calls off to several other private methods. Instead of passing around all of the "lookup data" I need for the business logic to each private method, I decided to use a singleton instance of a class named DataProvider that contains all of this "lookup data".
At the end of the routine, I "release" the DataProvider's lookup data so the next time the routine is executed, the latest lookup data will be used.
So, here's a simplified example:
public void Generate()
{
try
{
//populate singleton DataProvider with it's lookup data...
DataProvider.Instance.LoadLookupData();
//do business logic...
}
finally
{
//release provider's lookup data...
DataProvider.Release();
}
}
This works great until I have two different clients that execute the method at (or near) the same time. Problems occur because they share the same singleton instance and the task who finishes first will release the DataProvider before the other completes.
So...
What are my options here?
I'd like to avoid passing around all of the lookup data so the singleton pattern (or some derivative) seems like a good choice. I also need to be able to support multiple clients calling the method at the same time.
I believe the WCF service is configured as "Per-Call". I'm not sure if there's a way to configure a WCF service so that the static memory is not shared between service invocations.
Any help would be appreciated.

By default WCF is using "Per-Call", which means new instance of the WCF service is created for each client's call. Now since you implemented singleton even though new instance of the WCF is created it still calls your singleton.
If you would like to create lookup that is created for each call (like you have now) you should not do it as singleton. This way each client that calls your method will have new instance of the lookup, I think that was your intention.
However if you have lookup that is not changing that fast, I would recommend to share it between all calls, this will improve performance of your WCF service. You will need to declare your WCF service as
InstanceContextMode = InstanceContextMode.Single
ConcurrencyMode = ConcurrencyMode.Multiple
What this does is creating Singleton automatically for you by WCF, so you don't have to do it yourself, second it will support > 1 concurrent user (ConcurrencyMode.Multiple).
Now if you have your lookup that is changing and it needs to be reloaded after some period of time, I still would recommend using
InstanceContextMode = InstanceContextMode.Single
ConcurrencyMode = ConcurrencyMode.Multiple
but inside in your code cache it and then expire your cache at specific time or relative time (1 hours).
Here are some links that might help you:
3 ways to do WCF instance management (Per call, Per session and Single)
Hope this will help.

The static variables in a WCF service are always shared between instances regardless of the WCF InstanceContextMode setting. It seems you would be better off using a caching pattern for your look up data. The answers to this caching question provide some alternatives to rolling your own although they are a bit dated.
Also, if you decide that making the whole service instance a singleton (InstanceContextMode=Single) is the easiest solution be aware that you'll generally kill service scalability unless you also make your code multi-threaded (ConcurrencyMode=Multiple). If you can knock out thread-safe code in your sleep then a singleton service might be for you.

simplest is to use a synchronization mechanism - have you looked at lock(...) - this will act as a gatekeeper a lot like a critical section (if you have come across those in windows programming)
define a static object in your class
i.e.
static object lockObject = new object();
and use it in Generate method
i.e.
void Generate()
{
lock(lockObject)
{
...
}
}

Related

Singleton pattern in wcf

Is it advisable to use singleton pattern in wcf application?. I have ServiceResponse class which will take care the response and errordetail and almost all the details of the wcf current request. When i first hit the service, lets say i have 5 properties in ServiceResponse class and which got filled with respective values and some error details in errordetail property. For the next hit, lets say i dont get any error details and all other 4 properties got filled up.
But the thing here is, the errordetail property is still populated with the previous values which i assume the singleton object doesnt get created even after the subsequent hits. So only changed values got affected but untouched property still holds the previous value for the subsequent hits.
is it because the appdomain never get unloaded to release the object to allow the next sinleton object to get created for the other imm. request? How to acheive the singleton pattern in wcf otherwise. Appreciate the help.
The singleton pattern implies that the object is only instantiated once and lives for the entire lifetime of the AppDomain. You should not store data that is specific to a given request in static objects because all of them will share the same data which might not be what you are looking for.
Whether it is a good idea or not to use static objects in a WCF application is a question that will entirely depend on your scenario and what you need to store there. Since WCF is a multithreaded environment where multiple threads could access this shared data you will have to take special care to ensure that this data is thread safe by using the proper synchronization mechanisms.
is it because the appdomain never get unloaded to release the object
to allow the next sinleton object to get created for the other imm.
request?
There's a single AppDomain that gets created when your application starts. Don't expect to get a different AppDomain on each request. Requests will all be served from the same AppDomain until the application gets recycled by IIS.
...almost all the details of the wcf current request.
This is not a singleton. A singleton will per definition be shared between all requests. You want to create an instance that lives through the whole requets or connection context. Create an instance of your object and store it in the relevant request/connection cache the first time it is needed.

Class Designing in C# - DAL

I came across a Data Access Layer Class that was made up entirely of static methods. This class was consumed by a Web Application
For e.g
public class DataAccessLayer
{
Public static PersonDetails GetDetails(int iPersonID);
{
//implementation
}
Public static bool SaveDetails(PersonDetails objPerson);
{
//implementation
}
}
Is it a good practice to write such code. I can understand the fact that the performance will be slightly better when I use static methods, but will this cause any concurrency errors when multiple users call the Page?
Is it a good practice to write such code.
Firing offense in my teams, breaks so many good practices I suggest whoever writes something like that goes to my competitors and works for them.
I can understand the fact that the performance will be slightly better when I use static methods.
Like 0.000000000000000000001%?
but will this cause any concurrency errors when multiple users call the Page?
Depends how the methods are written. It violates object orientation, though, makes dependency injection harder, makes it hard to use proper transactional demarcations under a transaction coordinator and makes it hard to unit test / mock things.
Static or not, you may get concurrency issues, it depends very much on how the actual code in your data access methods is written (e.g. use of transactions, are there fields used for concurrency checking in your data source etc.).
The static variable dies in a standalone application, because the
garbage collector cleans all your object because your application has
ended.
But if you are using this in a webapplication, your application is not
dead until your web server dies. So even if you closes the web browser,
your web server is not close. Try to shut down your server and your
variable will be no more.

WCF Service and Threading

I have created a simple WCF (.NET 3.5) service which defines 10 contracts which are basically calculations on the supplied data. At the moment I expect quite few clients to make a call to some of these contracts. How do I make the service more responsive ? I have a feeling that the service will wait until it process one request to go to the next one.
How can I use multithreading in WCF to speed things up ?
While I agree with Justin's answer, I believe some more light can be shed here on how WCF works.
You make the specific statement:
I have a feeling that the service will
wait until it process one request to
go to the next one. How can I use
multithreading in WCF to speed things
up ?
The concurrency of a service (how many calls it can take simultaneously) depends on the ConcurrencyMode value for the ServiceBehavior attached to the service. By default, this value is ConcurrencyMode.Single, meaning, it will serialize calls one after another.
However, this might not be as much of an issue as you think. If your service's InstanceContextMode is equal to InstanceContextMode.PerCall then this is a non-issue; a new instance of your service will be created per call and not used for any other calls.
If you have a singleton or a session-based service object, however, then the calls to that instance of the service implementation will be serialized.
You can always change the ConcurrencyMode, but be aware that if you do, you will have to handle concurrency issues and access to your resources manually, as you have explicitly told WCF that you will do so.
It's important not to change these just because you think that it will lead to increased performance. While not so much for concurrency, the instancing aspect of your service is very much a part of the identity of the service (if it is session or not session-based) and changing them impacts the clients consuming the service, so don't do it lightly.
Of course, this speaks nothing to whether or not the code that is actually implementing the service is efficient. That is definitely something that needs looking into, when you indicate that is the case.
This is definitely pre-mature optimization. Implement your services first and see if there's an issue or not.
I think you'll find that you are worrying about nothing. The server won't block on a single request as that request processes. IIS/WCF should handle things for you nicely as-is.
I'm not familiar with WCF, but can the process be async?
If you are expecting a huge amount of data and intensive calculations, one option could be to send an id, calculate the values in a separate thread and then provide a method to return the result using the initial id.
Something like:
int id = Service.CalculateX(...);
...
var y = Service.GetResultX(id);
By default the Instancing is PerSession.
See WCF Service defaults
However if you use a session binding that doesn't support sessions (like BasicHttpBinding) or the the channel/client does not create a session then this behaves like PerCall
See [Binding type session support] (https://learn.microsoft.com/en-us/dotnet/framework/wcf/system-provided-bindings).
Each WCF client object will create a Session and for each session there will be a server instance with a single thread that services all calls from that particular WCF client object synchronously.
Multiple clients therefore would each have their own session and therefore server instance and thread by default and would not block each other.
They will only affect each other on shared resources like DB, CPU etc.
See Using sessions
Like others suggested you should make sure the implementation is efficient BEFORE you start playing with the Instancing and Concurrency modes.
You could also consider client side calculations if there is no real reason to make a call to the server.

A Question About C# and Static Classes and Functions

I've seen a lot of discussion about this subject on here.
If i have a static class w/ static methods that connects to a database or a server, is it a bad idea to use this in a multi-user environment (like a web page)? Would this make a new user's tread wait for previous users' threads to finish their calls before accepting a new one?
What would be the implications of this with multi-threading, also?
Thx!
If each static method is fully responsible for acquiring its resources and then disposing its resources within the scope of the method call (no shared state), then you shouldn't have any problem with threading that you wouldn't have using instance classes. I would suggest, however, that the bigger problem is that a reliance on public static methods (in static or non-static classes) creates many other design problems down the road.
First of all, you're binding very tightly to an implementation, which is always bad.
Second, testing all of the classes that depend on your static methods becomes very difficult to do, because you're locked to a single implementation.
Third, it does become very easy to create non-thread safe methods since static methods can only have static state (which is shared across all method calls).
Static methods do not have any special behaviour in respect to multithreading. That is, you can expect several "copies" of the method running at the same time. The same goes for static variables - different threads can access them all at once, there is no waiting there. And unless you're careful, this can create chaos.
Yes it's a bad idea.
When you use one connection for all your users if someone performs an action that requires, lets say 15 seconds, just for database access, all other users will have to wait in order to connect to the database
A little weirded out by this question. As to why you have so much static going on.
But I think you're asking about threading issues, so I would say go check out some of the docs on threading
http://msdn.microsoft.com/en-us/library/c5kehkcz(VS.80).aspx
Static is only defining the scope where the method is defined, and how it is bound / called. It has nothing to do with multi threading.
You need to be careful with static fields. They are shared by all threads. Threads are not waiting for each other, but you need locks to make it work.
But if your application is a bit more complex than Hello World, you should consider to have you methods not static but to use object oriented patterns.
If you do it right, it won't be a problem. If you do it wrong, it has the potential force sequential access to the resource.
Sometimes the difference between right and wrong can be very subtle and hard to spot, but the main thing is that no method should rely on or lock any "state" (members) of the class.
If you use one static connection to access the database, you will have to synchronize method calls. Multiple threads asking the database for data over a single connection will ... ehhmmm ... mess things up. So you are serializing all threads' data access and this will have a large impact on the performance.
If every call opens its own connection, you do not need to serialize all threads because there is no shared connection. Creating a connection per request is still an expensive design.
If you use a static connection pool you will reduce this performance impact because you only need to serialize the access to the connection pool.
Further, statics are in general not a good design decission - they make unit testing very complicated. You should consider using the Singleton or Monostate pattern.
I use static method for lookup objects. I can manage all lookups objects in one place (using caching) for the asp.net application and all methods call it by using static method.
By this way, I do not need to instantiate lookups objects everytime I need it and it reduce the need to call DB for performance enhancement.

Are static class instances unique to a request or a server in ASP.NET?

On an ASP.NET website, are static classes unique to each web request, or are they instantiated whenever needed and GCed whenever the GC decides to disposed of them?
The reason I ask is because I've written some static classes before in C# and the behavior is different than I would have expected. I would have expected static classes to be unique to each request, but it doesn't seem like that is the case.
If they are not unique to each request, is there a way to allow them to be?
UPDATE:
The answer driis gave me was exactly what I needed. I was already using a singleton class, however it was using a static instance and therefore was being shared between requests even if the users were different which in this case was a bad thing. Using HttpContext.Current.Items solves my problem perfectly. For anyone who stumbles upon this question in the future, here is my implementation, simplified and shortened so that it easy to understand the pattern:
using System.Collections;
using System.Web;
public class GloballyAccessibleClass
{
private GloballyAccessibleClass() { }
public static GloballyAccessibleClass Instance
{
get
{
IDictionary items = HttpContext.Current.Items;
if(!items.Contains("TheInstance"))
{
items["TheInstance"] = new GloballyAccessibleClass();
}
return items["TheInstance"] as GloballyAccessibleClass;
}
}
}
Your static classes and static instance fields are shared between all requests to the application, and has the same lifetime as the application domain. Therefore, you should be careful when using static instances, since you might have synchronization issues and the like. Also bear in mind, that static instances will not be GC'ed before the application pool is recycled, and therefore everything that is referenced by the static instance, will not be GC'ed. This can lead to memory usage problems.
If you need an instance with the same lifetime as a request, I would suggest to use the HttpContext.Current.Items collection. This is by design meant to be a place to store stuff that you need througout the request. For nicer design and readability, you can use the Singleton pattern to help you manage these items. Simply create a Singleton class that stores its instance in HttpContext.Current.Items. (In my common library for ASP.NET, I have a generic SingletonRequest class for this purpose).
Static members have a scope of the current worker process only, so it has nothing to do with requests, because different requests may or may not be handled by the same worker process.
In order to share data with a specific user and across requests, use HttpContext.Current.Session.
In order to share data within a specific request, use HttpContext.Current.Items.
In order to share data across the entire application, either write a mechanism for that, or configure IIS to work with a single process and write a singleton / use Application.
By the way, the default number of worker processes is 1, so this is why the web is full of people thinking that static members have a scope of the entire application.
Since the types are contained in an app domain, I would expect static classes to be present as long as the app domain is not recycled, or if the request gets served by a different app domain.
I can think of several ways to make objects specific to a particular request depends on what you want to do, for e.g. you could instantiate the object in Application.BeginRequest and then store it in HttpRequest object so that it can be accessed by all objects in the request processing pipeline.
If they are not unique to each request, is there a way to allow them to be?
Nope. Static members are owned by the ASP.NET process and shared by all users of the Web app. You'll need to turn to other session management techniques such as session variables.
Normally static methods, properties and classes are common at the Application level. As long as the application lives, they are shared.
You can specify a different behaviour by using the ThreadStatic attribute. In that case they will be specific to the current thread, which, I think, is specific for each request.
I would not advise this though as it seems overcomplicated.
You can use HttpContext.Current.Items to set stuff up for one request, or HttpContext.Current.Session to set stuff up for one user (across requests).
In general though, unless you have to use things like Server.Transfer, the best way is basically creating things once and then passing them explicitly via method invocation.

Categories

Resources