Multi-threading WCF with Singleton Pattern - c#

I have build WCF application and now I would like to run this service as multi-threaded.
I am running three threads in parallel and each thread has WCF service object. at the start of each thread I am executing login function to check user is valid or not & once valid then rest of the methods are gets executed using service object.
My question is, How can I create singleton pattern to create WCF Service object, which will do login are return me service object and same object then shared with multiple threads.
I looked into some articles but they have singleton with lock statement. But lock blocks other thread to use instance.
I need to share service instance with all threads & when all thread release the service object, I have to call logout method.
Any help would be appreciated.
Thanks

public class clsSingleton
{
private static clsSingleton instance = null;
clsSingleton()
{
}
public static clsSingleton Instance
{
get
{
if (instance == null)
{
instance = new clsSingleton();
}
}
}
public string GetName()
{
return "Name";
}
}
//How to call method GetName
string Name= clsSingleton .Instance.GetName();

Related

Using XML Webservices in ASP.Net statically or as a singleton

I have an ASP.Net site that consumes ASP.Net XML webservices. To communicate with each webmethod in the webservice I have a static class with static business methods, one for each webmethod in the webservice. The static business methods create a new instance of the webreference class each time they are called. The new instance of the webreference class is used to only call the webmethod, none of the properties in the instance of the webreference are changed from their defaults.
My question is can I create just a global static instance of the webreference class to use by all of the static business methods instead of creating a new one each time a static business method is called? (Basically are instances of a webreference class thread safe?)
My concern here is that the instance of the webreference class has some properties that are not thread safe and since the code is for a web site, multiple threads calling the same static business methods at the same time would cause issues between the threads.
The reason I'm asking is to try and find additional changes I can make to increase the site's performance. In tracing the site's performance I see a fair amount of time being spent on creating an instance of the webreference class. Additionally based on the garbage collection counters I'm seeing a lot of time being spent there too.
Example Code:
This is what I'm currently doing
public static class WebMethodWrapper
{
public static bool CallMethodA(string p1)
{
using(com.mysite.service1 _provider = new com.mysite.service1())
{
return(_provider.WebMethodA(p1));
}
}
public static bool CallMethodB(string p1)
{
using(com.mysite.service1 _provider = new com.mysite.service1())
{
return(_provider.WebMethodB(p1));
}
}
}
This is what I'd like to do
public static class WebMethodWrapper
{
static com.mysite.service1 _Provider = null;
static WebMethodWrapper()
{
_Provider = new com.mysite.service1();
}
public static bool CallMethodA(string p1)
{
return(_Provider.WebMethodA(p1));
}
public static bool CallMethodB(string p1)
{
return(_Provider.WebMethodB(p1));
}
}
My question is can I create just a global static instance of the webreference class to use by all of the static business methods instead of creating a new one each time a static business method is called? (Basically are instances of a webreference class thread safe?)
My concern here is that the instance of the webreference class has some properties that are not thread safe and since the code is for a web site, multiple threads calling the same static business methods at the same time would cause issues between the threads.
A jolly good question to which it seems you are well on the way to answering. I agree you should probably stick with your current approach where each static method creates its own local copy of the service client. This encourages thread-safety not only from the point of view of the client, but also guarantees that remote calls to the service are done so using unique proxies - where results are not potentially multiplexed with other requests.
If you went down the other route of using a shared instance, then you have to take into consideration those scenarios where the service faults in one thread.
Maybe there was a timeout?
Maybe some remote business logic failed?
Maybe the network failed because your room-mate is downloading the latest episode of Game of Thrones exceeding your download quota?
You would then need to invalidate that client and recreate a new one. All of this would need to be safely thread-locked. It sort of becomes quite complex to manage this orchestration.
Let's consider your alternative code:
public static bool CallMethodA(string p1)
{
return(_Provider.WebMethodA(p1));
}
Let's say this was successfully called the first time. Now imagine you need to call this 5 mins 5 seconds later but sadly by this time the server has severed the connection because it has a timeout of 5 mins. Your second call faults. The above code would need to be adjusted to allow for those scenarios. In our simple example below we recreate the client during a failure and try once more.
Perhaps:
public static class WebMethodWrapper
{
static com.mysite.service1 _Provider = null;
static object _locker = new object();
static WebMethodWrapper()
{
_Provider = new com.mysite.service1();
}
static com.mysite.service1 Client
{
get
{
lock (_locker)
{
return _Provider;
}
}
}
public static bool CallMethodA(string p1)
{
try
{
return (Client.WebMethodA(p1));
}
catch (Exception ex) // normally just catch the exceptions of interest
{
// Excercise for reader - use a single method instead of repeating the below
// recreate
var c = RecreateProxy();
// try once more.
return (c.WebMethodA(p1));
}
}
public static bool CallMethodB(string p1)
{
try
{
return (Client.WebMethodB(p1));
}
catch (Exception ex) // normally just catch the exceptions of interest
{
// Excercise for reader - use a single method instead of repeating the below
// recreate
var c = RecreateProxy();
// try once more.
return (c.WebMethodB(p1));
}
}
static com.mysite.service1 RecreateProxy()
{
lock (_locker)
{
_Provider = new com.mysite.service1();
return _Provider;
}
}
}
All of this could be wrapped-up in some generic service client cache that could maintain a collection of ready-to-go clients in a connection pool? Maybe a background thread periodically pings each client to keep them alive? An exercise for the reader perhaps.
Then again, sharing the same proxy instance between threads may not be a good idea from the service point of view, unless your service is marked as per-call which may or may not impact your design or performance.
Conclusion
Your current code is arguably safer and less complex.
Good luck!

ServerManager behaves differently in multiple threads

I created these properties in my static helper class.
private static ServerManager IISServerManager
{
get
{
if (mIISServerManager== null)
{
mIISServerManager= new ServerManager();
}
return mIISServerManager;
}
}
private static SiteCollection Sites
{
get
{
try
{
return IISServerManager.Sites;
}
catch (Exception)
{
return null;
}
}
}
When I'm calling Helper method
public static bool VirtualDirectoryExists(string dirName, string siteName)
{
if (!String.IsNullOrEmpty(dirName) && (Sites != null))
{
Site site = Sites[siteName];
...
in code that uses this helper (in Main thread) it retrieves all sites and their properties correctly.
On the other hand, when I'm calling it in code that uses this helper (in background worker thread) SitesCollection is retrieved, but code freezes on getting site with indexer [siteName]
Site site = Sites[siteName];
(it looks like deadlock, but there is no locking from my side)
The ServerManager class is documented as
"Any instance members are not guaranteed to be thread safe".
Which generally means you can't call them from a background thread because there's no way to do any locking to ensure IIS isn't accessing data at the same time in the main thread.
Simply get what you need while in the main thread, cache it, then use it in a background thread.

Global Variable between two WCF Methods

I have two Methods in a WCF Service say
Method1()
{
_currentValue = 10;
}
Method2()
{
return _currentValue;
}
I have a situation in which, i need to set a value in Method1() and read it in Method2().
I tried using static variable like public static int _currentValue, i could able to read the value set in Method1() in Method2().
But the issue is, i want this variable to react like separate instance variable for each request made. i.e., right now below is the problem
Browser 1 :
- Method1() is called
=> sets _currentValue = 10;
- Method2() is called
=> returns _currentValue = 10;
Browser 2:
- Method2() is called
=> returns _currentValue = 10;
Actually the value set is Browser 1 is static, so in Browser 2
the same value is retrieved.
What i am trying to implement is the variable should act like a new instance for each request made (when calling from each browser). What should i use in this case? a session?
You're going to need some mechanism for correlation because you have two completely different sessions calling into different methods. So I would recommend using a private key that both callers know.
It is a bit impossible for me to know what that key can be because I can't really gather anything from your question, so only you know that, but the simple fact is you're going to need correlation. Now, once you determine what they can use you can do something like this.
public class SessionState
{
private Dictionary<string, int> Cache { get; set; }
public SessionState()
{
this.Cache = new Dictionary<string, int>();
}
public void SetCachedValue(string key, int val)
{
if (!this.Cache.ContainsKey(key))
{
this.Cache.Add(key, val);
}
else
{
this.Cache[key] = val;
}
}
public int GetCachedValue(string key)
{
if (!this.Cache.ContainsKey(key))
{
return -1;
}
return this.Cache[key];
}
}
public class Service1
{
private static sessionState = new SessionState();
public void Method1(string privateKey)
{
sessionState.SetCachedValue(privateKey, {some integer value});
}
public int Method2(string privateKey)
{
return sessionState.GetCachedValue(privateKey);
}
}
It sounds like you may need to use the per session instance context mode for the WCF service. This will allow you to maintain state on a per session basis, so member variables in the service instance will persist between method calls from the same proxy instance. Because each user has their own session, the state of the service instance will vary by user.
Check out this article for more information: http://msdn.microsoft.com/en-us/magazine/cc163590.aspx#S2
You have made your variable static, and this is what's causing the problem. static means that every instance of your class shares the variable, but all you really need is a variable declared outside of your methods, like this:
private int _currentValue;
Method1()
{
_currentValue = 10;
}
Method2()
{
return _currentValue;
}
This variable will be reated separately for each instance of your class - preserving this value between requests for a given user is a separate problem. (A session is one possible solution.)
WCF has provided three ways by which you can control WCF service instances:
Per call
Persession
Single instance
You will find the best solution by reading this
Three ways to do WCF instance management
Seems like an old thread but in case somebody is still interested, this can be achieved by just asking WCF to run a single instance of your service. Add the following line (decorator) to the definition of your class
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
If you want the behavior only for the same session but not across clients then you can mark it as per session by the following service behavior
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
The other option is per call which is the default option.
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]

Object instances in static classes

I am developing a web application with multiple WCF service references. Currently, each time we need to make a call to a service we do the following(as an example):
Service.ServiceClient ServiceClient = new Service.ServiceClient();
ServiceClient.SomeMethod();
Would it be better to have a static class with static references to each Service and call that class instead, thereby avoiding creating a new instance of the ServiceClient object each time we want to call it?
For example:
public static class Services
{
private static Service.ServiceClient _ServiceClient = new Service.ServiceClient();
public Service.ServiceClient ServiceClient
{
get
{
return _ServiceClient;
}
}
}
And, if doing it this way, would the line
private static Service.ServiceClient _ServiceClient = new Service.ServiceClient();
cause a new object to be created each time we try to call that object, or will it be the same instance of that object every time we make a call to it?
You can have a class which will have all the functions exposed by your data contract. All these methods will be static. Now inside these function you can do as follows
public class ServiceManager{
public static CalculatedData SomeMethod()
{
var client = GetClient();
try
{
return client.SomeMethod();
}
catch(Exception ex)
{
//Handle Error
}
finally
{
if(client.State == System.ServiceModel.CommunicationState.Opened)
client.Close();
}
}
private static SomeClient GetClient()
{
return new ServiceClient();
}
}
Consumer will consume it like
var calculatedData = ServiceManager.SomeMethod();
if you want to do so create
Singleton Service
The singleton service is the ultimate sharable service. When a service is configured as a singleton, all clients independently get connected to the same single well-known instance, regardless of which endpoint of the service they connect to. The singleton service lives forever and is only disposed of once the host shuts down. The singleton is created exactly once, when the host is created.
You configure a singleton service by setting the InstanceContextMode property to InstanceContextMode.Single:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
class MySingleton : ...
{...}
It will only be created once, you will have no control however over when it will be created. The usual way to handle this is either create a seperate static method (init for example) where you create the instance or create it when first called. You should check the singleton design pattern for this.
You could use a helper like the following:
private delegate void ServiceAction(Service.ServiceClient client);
private static void PerformServiceAction(ServiceAction serviceAction)
{
using (var client = new Service.ServiceClient())
{
serviceAction(client);
}
}
which can then be invoked the following way:
Helper.PerformServiceAction(client => client.SomeMethod());
It still creates a proxy for every call or sequence of calls but at least your calling code is lighter.
(Keep in mind that using 'using' with a wcf client proxy is not a good idea because dispose might throw an exception so it's better to catch exceptions and to close the proxy gracefully manually).

Singleton Data Access Layers

In our data access layer at work we have this standard implementation where the class is accessed through a singleton public property which looks something like this:
public static CustomerController Instance
{
get
{
lock(singletonLock)
{
if( _instance == null )
{
_instance = new CustomerController();
}
return _instance;
}
}
}
now, I get what the code is doing, but I was wondering why you would do this over just creating an instance of the class each time it is used?
EDIT: Oh whoops I didn't catch the "Data Access Layers" part. But I have an example of that too: If your multithreaded app funnels all of its' database calls through a singleton class, only one thread will ever access the database at once, avoiding race conditions.
If you have a logging mechanism in a multi-threaded application that you use to spit out all exceptions and just write info in (especially for services, or apps that are always running, printing out statuses whenever stuff happens), you will run into file-locking issues. I use a singleton logger class, so that only one thread ever will have access to the Logger, and the rest will wait until the Logger is free to write their line in the text file.
There are lots of cool reasons to use a singleton, but I was like you and had no idea what they were FOR until I ran into this issue with file access in a multithreaded app.
You may wish to do this also, its double checked locking, it will speed up access to your singleton
public static CustomerController Instance
{
get
{
if( _instance == null )
{
lock(singletonLock)
{
if( _instance == null )
{
_instance = new CustomerController();
}
}
}
return _instance;
}
}
The answer is quite simple: you want to get the same object each time it's used.
It gives you the advantages of being a global variable (i.e. there's only one) with the advantages of being a class object (amongst other things, it can do invisable initialization the first time it's needed).

Categories

Resources