Does the garbage collector clean up web service references or do I need to call dispose on the service reference after I'm finished calling whatever method I call?
Instead of worrying about disposing your web services, you could keep only a single instance of each web service, using a singleton pattern. Web services are stateless, so they can safely be shared between connections and threads on a web server.
Here is an example of a Web Service class you can use to hold references to your web service instances. This singleton is lazy and thread-safe. It is advised that if you make your singletons lazy, they are also kept thread safe by following the same logic. To learn more about how to do this, read the C# In Depth article on Implementing Singletons.
Also keep in mind that you may run into issues with WCF web services. I'd recommend reading up on WCF's instance management techniques article, specifically the singleton section, for more details.
public static class WS
{
private static object sync = new object();
private static MyWebService _MyWebServiceInstance;
public static MyWebService MyWebServiceInstance
{
get
{
if (_MyWebServiceInstance == null)
{
lock (sync)
{
if (_MyWebServiceInstance == null)
{
_MyWebServiceInstance= new MyWebService();
}
}
}
return _MyWebServiceInstance;
}
}
}
And then when you need to access your web service, you can do this:
WS.MyWebServiceInstance.MyMethod(...)
or
var ws = WS.MyWebServiceInstance;
ws.MyMethod(...)
I've successfully used this pattern on several projects and it has worked well, but as tvanfosson mentions in the comments below, an even better strategy would be to use a DI framework to manage your web service instances.
I think the DataService inherits Dispose from Component.
Objects that implement IDispose should be disposed of manually to assist the garbage collector.
If you object is short lived use a using block. For objects that can be retained ensure that they object that retains them disposes of them when it is also disposed.
what are you trying to accomplish here?
If your worried about performance, then I would worry more about the responsiveness of the server hosting the webservice and the network speed, as they can dramatically affect the length of time you have to wait for the webservice call to complete (unless its asynchronous).
The examples on MSDN dont call 'Dispose' and its quite obvious that the garbage collector will do its job, so unless your working on a realtime system that needs to process over 100,000 records in memory every second, then maybe you dont need to come up with a way to dispose resources or manage memory.
I think the concerns of Seabizkit in the above answer are very legitimate.
It's quoted here:
#DanHerbert what happens when two threads call the singleton.. let me explain... there is a lock on the object.. to make it thread safe. Does that mean that if theard1 call accesses webInstance, then thread2 will wait on thread1 to finish. or is the lock purely for the creatation of the instance. say you have 10 callers.... does the lock mean they are chained... or async, i think you will get what I'm asking let me know if it wasn't clear. – Seabizkit Oct 13 '16 at 10:01
<
After I've done some testing I can tell that you won't be able to get any good performance when a single 'client' object is used by multiple different threads.
If ten threads are created and they all are using the same singleton 'client' then they will have to wait in line until all previous calls are done.
To see the proof for that please read and run a sample in this c-sharp corner article here:
https://www.c-sharpcorner.com/article/increase-performance-with-an-object-pool-or-why-singleton-may-cause-performance/
titled "Increase Performance with an Object Pool or Why Singleton May Cause Performance Issues".
Sorry to burst the bubble of the singleton web service users. Also, you would be very hard-pressed to find Microsoft's example where the web service client is "caged" in the singleton.
Related
I read this question, but the answers and discussions are confusing myself.
So I decided to check, but how could I do it? How to create a test to prove if HttpWebClientProtocol class is Thread Safeor not?
I have already done the following test:
Create one HttpWebClientProtocol to call a WS.
I create the WS by myself and have just a Thread.Sleep(30000) inside.
So I create two independent threads to call this HttpWebClientProtocol at the same time.
The result is: Both threads called the WS with no problems. (One thread didn't need to wait the first call ends)
with this test have I proved that the object IS Thread Safe and the "correct' answer of the other question is wrong??
Well... I have a better test for you.
HttpWebClientProtocol Class
Directly from MSDN. Here's a copy/pasta of what they have to say about thread safety:
Thread Safety
The properties on this class are copied into a new instance of a WebRequest object for each XML Web service method call. While you can call XML Web service methods on the same WebClientProtocol instance from different threads at the same time, there is no synchronization done to ensure that a consistent snapshot of the properties gets transferred to the WebRequest object. Therefore, if you need to modify the properties and make concurrent method calls from different threads you should use a different instance of the XML Web service proxy or provide your own synchronization.
About thread safety
It's not about just "being available". But it's about making sure that data/state being affected by one thread does not affect the correct execution of the other thread.
If they share data structure and those structure are shared between threads, they are not thread-safe. The issue might not be easily apparent but on a system with large amount of usage of that class in a multi-threaded system, you could find some bugs/exceptions/weird behaviors that you will not be able to reproduce in a development environment and "only happens in production".
That my friend, is NOT thread safe.
About HttpWebClientProtocol and why it's not thread-safe
While the documentation is clear about being able to reuse the HttpWebClientProtocol, it is important to know that all the properties of the object itself are not going to be persisted to other requests created on another thread.
Meaning that if you have 2 threads playing with the Credentials property, you might end-up with some requests with different credentials. This would be bad in a web application with impersonation where requests could be done with a different credential and you could end-up with the data of someone else.
However, if you only need to set the initial properties once, then yes. You can reuse the instance.
I have a self hosted WCF service. It offers a processing function DoSth().
The processing might take long so I need to return OK to the caller prior
to finish the task. Currently I've implemented that by calling
Task.Factory.StartNew(() => DoWork());
Might it be possible that the garbage collector interferes so that the just created task may never finish?
If the program is self hosted, I would say that it does not interfere as long
as the host is running (static variables also remain their value).
Please correct me if I'm wrong.
But how would garbage collection react if the service is hosted in IIS?
If it interferes is there a way to prevent it?
The GC is never going to collect an object that might possibly be accessed by an executable code in the future (at least through any managed reference). That's how it is designed.
If there's any possible way for some code to execute that would use the object, then the GC isn't allowed to clean it up. It only cleans up objects that it can prove are never going to be accessed by any executable code ever again.
Since this task, the delegate it was given, and the objects used within the delegate can all be accessed by the thread that will be processing this request, they're all accessible, and are not eligible for collection.
Basically the only time you ever need to even consider the question of, "is the object I'm trying to use potentially going to end up cleaned up by the GC before I'm done with it" is when you're dealing with non-managed references, such as when using the WeakReference class or when interoping with other languages.
I'm writing a series of ASP.Net Web Api services that basically get data from a database and return it.
We decided for now to reuse previous poorly written Data Access Objects (let's call them PoorDAO) that use ADO.Net to call stored procedures in the database.
One improvement in the future will be to rewrite that data access layer to benefit from Async data calls with Entity Framework.
Because of this, we decided to wrap the PoorDAO's in Repositories implementing an interface that exposes asynchronous methods. The idea is to keep the same interfaces for future EF asynchronous repositories :
// future common interface
public interface ICountryRepository
{
Task<Country> GetAllCountries();
}
// current implementation hiding a PoorDAO in shame
public class CountryRepository : ICountryRepository
{
public Task<Country> GetAllCountries()
{
var countries = PoorCountryDAO.GetAllcountries(); // poor static API call
// some data transformation ...
return Task.FromResult(result);
}
}
What we have here is basically a synchronous operation hiding in asynchronous clothing. This is all fine, but my question is : while we're at it, wouldn't it be better to make the method entirely async and call await Task.Run(() => poorCountryDAO.GetAllcountries()) instead of just poorCountryDAO.GetAllcountries() ?
As far as I can tell, this would free up the IIS thread the Web Api service HTTP request is currently running on, and create or reuse another thread. This thread would be blocked waiting for the DB to respond instead of the IIS thread being blocked. Is that any better resource wise ? Did I totally misunderstand or overinterpret how Task.Run() works ?
Edit : I came across this article which claims that in some cases, asynchronous database calls can result in an 8 fold performance improvement. His scenario is very close to mine. I can't get my head around how that could be possible given the answers here and am a bit perplexed about what to do...
Is that any better resource wise?
No; it's provably worse. The existing Task.FromResult and await is the best solution.
Task.Run, Task.Factory.StartNew, and Task.Start should not be used in an ASP.NET application. They steal threads from the same thread pool that ASP.NET uses, causing extra thread switches. Also, if they are long-running, they will mess with the default ASP.NET thread pool heuristics, possibly causing it to create and destroy threads unnecessarily.
It's the same thing, you're locking up a thread while releasing another one. In theory performance is the same, although it will actually be slightly worse because of the overhead of context switching
A few points: first, for await Task.Start(() => poorCountryDAO.GetAllcountries()), Task.Start(() => poorCountryDAO.GetAllcountries()) already gives you a task, so you should just return that instead rather than awaiting.
Note that in any case, the fact that this method's Task is really synchronous is an implementation detail. There may be a temptation to wrap the GetAllCountries() call itself in a background thread, but that's a bad idea.
In all of these cases, you're still going to be stuck wasting a thread. The scenario you desire where you free up the IIS thread completely requires the use of "Overlapped IO" for the database calls (as per your link).
Basically, in these cases right now, one way or another, a thread (either the main thread or a worker thread) are going to block when they call PoorCountryDAO.GetAllcountries(). However, when you switch to the asynchronous DB calls, they will no longer burn a thread at all. If, however, the caller uses its own Task.Run, that will now come back to bite you.
We're working with a 3rd-party legacy system that requires thread affinity for some of the tear-down logic. We're also hosting a WCF service inside IIS which, under heavy loads will do a rude unloading of our app domain. In these cases it falls to the critical finalizer to do cleanup. Unfortunately, without thread affinity in the finalizer, the 3rd-party system deadlocks.
So roughly:
public class FooEnvironment : CriticalFinalizerObject, IDisposable
{
public FooEnvironment()
{
// start up C API
}
public bool Dispose()
{
// shutdown C API (from same thread ctor was called on)
}
~FooEnvironment()
{
// try to shutdown C API but deadlock!
}
}
I've tried various things where we Run with the ExecutionContext from the initializing thread, but this doesn't work (at least in IIS) and we get an invalid operation exception stating that this execution context can't be used (ostensibly because it may have been marashalled across AppDomains, which seems likely).
I've read several things basically stating that what I'm trying to do can't be done but I figured I would ask since there isn't a lot of information on this topic.
Back in the old days I developed a library that wrapped the hideous DDEML which is a Win32 api wrapper around the DDE protocol. The DDEML has thread affinity requirements as well so I feel your pain.
The only strategy that is going to work is to create a dedicate thread that executes all of your library calls. This means biting the bullet and marshaling every single request to call into this API onto this dedicated thread and then marshaling back the result to the original thread. It sucks and its slow, but it is the only method guaranteed to work.
It can be done, but it is painful. You can see how I tackled the problem in my NDde library. Basically, the finalizer will simply post a message via static method calls to a thread that can accept and dispatch them to the appropriate API call. In my case I created a thread that called Application.Run to listen for messages because DDE required a Windows message loop anyway. In your case you will want to create the thread in a manner that monitors a custom message queue. This is not terribly difficult if you use the BlockingCollection class because the Take method blocks until an item appears the queue.
I am implementing my first REST service in .NET 4 and have encountered something unexpected. It seems that I do not understand the underlining workings of Microsoft's ServiceModel, but could not find the answer in the traditional way.
To implement my web service I was following the steps in this tutorial: http://blogs.msdn.com/b/endpoint/archive/2010/01/06/introducing-wcf-webhttp-services-in-net-4.aspx
The service works. What surprised me was that Application_BeginRequest and Application_EndRequest in Global.asax are called by different threads. Looking at stack trace it appears that these threads are based in some kind of thread pool.
Without doing some refactorings this is a problem for us since we were always assuming that a single request would always run on the same thread, due to which we were keeping some variables stored in the thread local storage. The variables are initialized in Application_BeginRequest and released in Application_EndRequest. It appears that with ServiceModel this is not the right approach.
My questions are:
Can I make any assumptions about which threads are running my code when I am using ServiceModel?
Is there any way to restrict the execution to a single thread? Would this be bad for any reason?
What is the right way of storing a variable for the duration of request when using ServiceModel?
Thank you.
One thing I'd suggest is to consider using the WCF hooks rather than the Application_BeginRequest and Application_EndRequest methods. Four instance, here are four of the more useful hooks:
AfterReceiveRequest -> BeforeCall -> Method call -> AfterCall -> BeforeSendReply
There hooks are pretty powerful. You an inspect parameters before your method is called (centralize some logging to one place) and do all sorts of other useful things. These are not the only hooks available, there are some others I use as well. For instance GetInstance allows me to override creation of the service class object (so you can use dependency injection frameworks, etc).
When I use the per call concurrency mode, these hooks plus the method call itself ALL get called on the same thread. Hope this helps. I can provide links to implementing these hooks if you like.
Cheers
You may want to look at the [ServiceBehavior] attribute on your service implementation, since it supports arguments to control how many instances get created and what threading model is used.
http://msdn.microsoft.com/en-us/library/cc681240.aspx
When you have
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single,
ConcurrencyMode = ConcurrencyMode.Multiple)]
public class MyService : IMyService
your service will run as a singleton but with multiple threads--up to a threshold set in the WCF config--calling into your methods. To force it to run on only one thread and thereby serialize inbound requests, set ConcurrencyMode.Single.
Alternatively, you could spin up a new instance of your service for each call:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall,
ConcurrencyMode = ConcurrencyMode.Single)]
public class MyService : IMyService
The instance will have only one thread accessing it. In fact, when you have InstanceContextMode.PerCall, then the ConcurrencyMode is ignored because it's always "Single", and each instance is running in its own thread.