I have a WebService, which owns a Singleton:
public class WebService
{
private static Singleton _singleton = Singleton.Instance;
public void DoSomeJob(object jobObj) {
_singleton.QueueJob(jobObj);
}
}
.. and the Singleton, which should be threadsafe.
public static Singleton Instance
{
get
{
lock (_syncRoot)
{
if (_instance == null)
_instance = new Singleton();
return _instance;
}
}
}
}
What I was going to achieve this way is, that every client calling my WebService gives its object to the same instance of the singleton. This singleton again, does not really do more than queueing the object and processing it when a timer ticks.
The problem I was facing (and still am), is that the Singleton is getting killed every time the WebService terminates. However, I am not sure if this is happening because the owner of the Singleton is being destructed or for some reason given by the app pool settings.
I have tried to make the app pool "always running" and "suspending" when idle, instead of "on demand" and "terminate" - no success :-/
Why is the Singleton getting killed off each time? How can I keep the Singleton's instance alive between WebService executions?
Why is the Singleton getting killed off each time?
You need to understand about how WCF manages service instancing to understand why this is. By default WCF will create a new service instance per client over a session-enabled binding, or per call if no session is supported.
This means that the service instance which is dispached to handle a client call will load an instance of your singleton into memory. However, when either the the client session, or individual call (where no session is supported) has finished, the instance is unloaded, which means your singleton will also get unloded.
How can I keep the Singleton's instance alive between WebService
executions?
There are two ways to do this:
Get rid of your singleton. Use a backing data store to maintain your state across mutliple clients calls.
Use a singleton service instance, by setting InstanceContextMode=InstanceContxtMode.Single in your service implementation declaration.
Of the two options I would go with option 1. This is because singleton service instances are generally an anti-pattern because they do not scale, and should only be used when there is no alternative.
....considered to implement the queueing functionality to an external
component, e.g. a windows service, but for the purpose of simplicity
and reduced complexity I would like to implement that within the
WebService
OK, right there is where I think the source of your problem is. There is a common belief around ditributed systems, which can be stated as the following:
Simple = fewer components, and
Complex = more components
I would modify that belief to:
Simple = simple components, and
Complex = complex components
In my opinion your decision to embed your timer/queueing requirement into your web service automatically makes your component complex.
I think breaking out the component which reads from the queue into another component is exactly what you need to do!
If this is daunting to you, then I would very strongly recommend using topshelf to manage your windows service, which is a free framework which makes the creation and deployment of services very simple.
Related
I have a server which exposes a SOAP WCF service endpoint. This server also uses a group communication framework called Ensemble (not really relevant to the question) in order to communicate with other servers in the same cluster.
I need to share objects/data between the seperate thread which listens for incoming messages from other servers and the threads that run the WCF routines when they are invoked. So far, I did the most simple thing I could think of - I created a static "database" class with static members and static methods - and used lock() to sync. This way I could access this class from both the server and the group communication thread. My problem with this is that it kinda breaks the whole "OOP thing" and I think something more clever can be done here...
If the only issue that you have with your solution is its alleged "non-OOP-edness", you could go for the Singleton Pattern instead. This is a widely used pattern for situations when you must have a single instance of a class that needs to be shared among multiple parts of the system that are otherwise disconnected. The pattern remains somewhat controversial, because some regard it as a glorified version of a global variable, but it is efficient at getting the job done.
Encapsulate the seperate thread which listens for incoming messages from other servers into a Class say MyCustomService.
Write the WCF service Implementation class with behaviour as concurrencyMode multiple and InstanceContextMode Single
Write a event delagate inside the WCF service implementation class. The delegate will return type of the MyCustomService class.
When you instantiate the WCF service programmatically, (host.Open), before that set the delegate to a function that will return the MyCustomService instance which can be singleton or static.
From the service instance class you can always call the delegate to get the MyCustomService instance. Check for null though.
Do I really need to dispose a SoapHttpClientProtocol object?
Is it better practice to use the instance as a Singleton in ASP.Net?
This says that SoapHttpClientProtocol is Thread Safe:
http://msdn.microsoft.com/en-us/library/system.web.services.protocols.soaphttpclientprotocol.aspx.
The fact that it is thread-safe means that using it as singleton will reduce your site almost to a single-threaded application.
Proxies - especially for a web application - should always be created as temporary object inside a using block (although in WCF it needs to be a different approach). This approach will have its overhead of creating a proxy every time but is the safest approach. This will prevent different clients of the ASP.NET application clashing with each other or using a closed or faulted proxy.
I have an ASP.NET application which uses a component in an class library assembly to make web service calls. The component uses the Thread Pool or some sort of home brewed threading solution to spawn background threads in which synchronous web service calls are made.
A logging component is used in the ASP.NET application and by helper classes that the component calls from the background threads spawned when it does service calls.
In ASP.NET a HttpModule creates logging context object and stores it in the HttpContext.Current.Items collection. The helper classes used in the ASP.NET application and in the helper classes fetch the logging context object from HttpContext.Current.Items when a message needs to be logged in order to decorate the logged message with information that puts the logged message into a context.
When the helper classes are called directly from ASP.NET, HttpContext.Current is available.
When the helper classes are called from background threads created by the component, HttpContext.Current is null and so there is no logging context available to them when messages are logged; the logged messages are useless.
I don't have control over the component which creates the threads for making service calls. If I did, I would arrange for the logging context obect to be copied and passed into the child thread.
My logging context object cannot be static, because it would be overwritten by concurrent ASP.NET request threads and that would be bad.
The members of my logging context object (simple int/string properties) could be marked ThreadStatic, which would work, and I would not need to use HttpContext.Current.Items anymore.
What I really need is a to make the .NET runtime copy the object (or even pass a reference; either would do) and makes it available to child threads automatically.
I was wondering whether I could add a <system.threading> element to web.config and nominate a helper class for creating threads like you can do for Web Requests in %lt;system.net>
I also wondered whether I could mark my Logging Context object with some attribute that causes it to be copied automatically.
I looked into log4nets LogicalThreadContext, tried it, but it didn't work. I think that's for passing logging context information across processes or appdomain boundaries.
What mechanism does log4net's LogicalThreadContext used behind the scenes? Something from System.Runtime.Remoting? Is that deprecated now?
My environment is .NET 4, so maybe with the parallel extensions or enhancements to threading in .NET 4 this is now possible.
Anyone any idea if this is at all possible? I'm beginning to think not.
Update *
I have had to do the following:
Task<IEnumerable<Account>> accountsTask = Task<IEnumerable<Account>>.Factory.StartNew
(
instrumentationContext =>
{
var parentContext = instrumentationContext as Site.Instrumentation.InstrumentationContext;
if (Site.Instrumentation.InstrumentationContext.Current == null && parentContext != null)
Site.Instrumentation.InstrumentationContext.Current = parentContext;
return GetAccounts();
},
Site.Instrumentation.InstrumentationContext.Current
);
Where the GetAccounts() method calls on another class which in turn depends on Site.Instrumentation.InstrumentationContext.Current
The problem is, I would rather NOT have to change the code to explicitly pass in and set this state object in the child thread - I want the .NET Framework to do that for me automatically, so that the code (above) that creates the task is none the wiser and does not have to be changed.
If no-one else contributes with alternatives, Jon gets the green tick as I figured that was my only realistic choice albeit with tasks not threads.
If I understand you correctly all you need to do is to pass an object to a thread signature so what's wrong with a parameterized thread start ??
static void Main(string[] args)
{
object j = new object();
Thread t = new Thread(()=>childThread(j));
t.Start();
}
private static void childThread(object someObject)
{
// do work
}
I have a WCF service configured like this:
InstanceContextMode = InstanceContextMode.PerCall,
ConcurrencyMode = ConcurrencyMode.Multiple
I have a method where I call the service about ten times per second for about 30 seconds. Randomly, the service stop to work and the client is stopped on the line where the service is called.
On the server side, I have a static object "MyStaticObject" (Not declared in my service, this is an other class on the server). This object is a Dictionnary that contains some instanced objects in which there is a backgroundworker.
I don't think there is a deadlock in the database since it lock when I try to access the service and not when I try to access the database.
I currently lock my dictionnary this way:
lock (MyClass.MyStaticLockObject)
{
MyClass.MyStaticObject...;
}
I'd like to know what could cause this kind of weird behavior.
I've seen WCF services lock-up under high loads if you're creating a new proxy object on the client-end for each operation. Are you sure you're not creating 10 proxy instances per second?
If you're accessing a static instance of a Dictionary, you may want to consider locking it when you do read/write operations, eg:
lock (MyStaticObject)
MyStaticObject.Add("Foo", foo);
lock (MyStaticObject)
foo = MyStaticObject["Foo"];
Alternatively, you could try using a thread-safe implementation of Dictionary, such as the one in this article, which uses ReaderWriterLockSlim to maintain separate locks for reading and writing.
BTW: for those incredulous that a service would be called 10 times per second, I currently work on a project where it performs quite nicely on 100 calls per second--and will have to where it gets deployed.
I'm using a singleton pattern for the datacontext in my web application so that I dont have to instantiate it every time, however I'm not sure how web applications work, does IIS open a thread for every user connected? if so, what would happend if my singleton is not thread safe? Also, is it OK to use a singleton pattern for the datacontext? Thanks.
I'm using a singleton pattern for the datacontext in my web application
"Singleton" can mean many different things in this context. Is it single-instance per request? Per session? Per thread? Per AppDomain (static instance)? The implications of all of these are drastically different.
A "singleton" per request (stored in the HttpContext) is fine. A singleton per session is discouraged, but can be made to work. A singleton per thread may appear to work but is likely to result in unexpected and difficult-to-debug behaviour. A singleton per Application or AppDomain is a disaster waiting to happen.
so that I dont have to instantiate it every time
Creating a DataContext is very, very cheap. The metadata is globally cached, and connections aren't created until you actually execute a query. There is no reason to try to optimize away the construction of a DataContext instance.
however I'm not sure how web applications work, does IIS open a thread for every user connected?
IIS uses a different thread for every request, but a single request may use multiple threads, and the threads are taken from the Thread Pool, which means that ultimately the same user will have requests on many different threads, and conversely, different users will share the same thread over multiple requests and an extended period of time. That is why I mention above that you cannot rely on a Thread-Local Singleton.
if so, what would happend if my singleton is not thread safe?
Very bad things. Anything that you cache globally in an ASP.NET application either needs to be made thread safe or needs to be locked while it is in use.
Also, is it OK to use a singleton pattern for the datacontext? Thanks.
A DataContext is not thread-safe, and in this case, even if you lock the DataContext while it is in use (which is already a poor idea), you can still run into cross-thread/cross-request race conditions. Don't do this.
DataContext instances should be confined to the scope of a single method when possible, using the using clause. The next best thing is to store them in the HttpContext. If you must, you can store one in the Session, but there are many things you need to be aware of (see this question I answered recently on the ObjectContext - almost all of the same principles apply to a DataContext).
But above all, do not create "global" singleton instances of a DataContext in an ASP.NET application. You will deeply regret it later.
Many people keep the DataContext around for the duration of the request by keeping it in the HttpContext.Current.Items Thereby it is also private to the request.
Have a look at this blogpost by Steve Sanderson, and the UnitOfWork pattern.
Static variables are visible to all users on the per app domain, not per session. Once created, the variable will sit in memory for the lifetime of the app domain, even if there are no active references to the object.
So if you have some sort of stateful information in a web app that shouldn't be visible to other users, it should absolutely not be static. Store that sort of information in the users session instead, or convert your static var to something like this:
public static Data SomeData
{
get
{
if (HttpContext.Session["SomeData"] == null)
HttpContext.Session["SomeData"] = new Data();
return (Data)HttpContext.Session["SomeData"];
}
}
It looks like a static variable, but its session specific, so the data gets garbage collected when the session dies and its totally invisible to other users. There safety is not guaranteed.
Additionally, if you have stateful information in a static variable, you need some sort of syncronization to modify it, otherwise you'll have a nightmare of race conditions to untangle.
#ryudice the web server creates a new thread for each request. I think the best approach is to have a datacontext bound to each request, meaning that you should create a new datacontext every time you serve a request. A good way of achieving this is by using a DI tool, such as StructureMap. These kind of tools allow you to setup the lifecycle of the instances you configure, so for example in your case you would configure your XDataContext class to be HttpContext scoped.
Regards.
here are Microsoft's examples on how to do multi-tier with LINQ-To-SQL.
http://code.msdn.microsoft.com/multitierlinqtosql