I have a non-singleton WCF (standalone) service running some COM objects. In non-WCF environments, using Thread.Start, these COM objects happily run in parallel in different threads, utilising all CPUs and completing around the same time.
However, when I try using them in a specific WCF service, things get strange.
When in the registry ApartmentState is set to Both, WCF works, but the tasks seem to be serial, waiting for each other's completion. The CPU usage never exceeds a share of 1 CPU. It's as it is forced to run in STA.
When in the registry ApartmentState is set to Free, it crashes.
I simply don't get it. Is this some kind of piece of plumbing getting in the way?
My WCF service class has the following attributes:
[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any, InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)]
The COM objects are static / global.
Looks like I might have an answer. Posting in case someone else comes across a similar mystery. The older version was STA only, and the Interop was set to be embedded. Additionally, a prototype of a method was changed. Seemingly, parts taken from the embedded Interop clashed with the COM itself.
Once I changed the setting to No and recompiled everything, it become normal.
Related
We are having a problem with a memory leak between our MVC3 web application and our WCF data layer service.
I believe the problem is from the WCF side, although cannot track it down. I've searched the web and these forums, but have not been able to find the cause. Any help would be much appreciated!
So - the initial symptom was the size of the w3wp process associated with the backend growing constantly. We can see it grows by a variable amount (order of magnitude 100kb) every time a simple call is made from the web app that calls a service.
Running Jetbrains memory profile against the app we can see that
System.ServiceModel.Channels.TransmissionStrategy.SlidingWindow
is by far and away the culprit. At app startup there are 4 objects instantiated with a tiny amount of memory (6.4% of total), after mild use it rises to > 200 objects, ~50% of total. Continued use drives this towards 100%. I've never heard of this before, but some googling indicates that it is used (amongst other things) in the transmission of data to and from the WCF layer.
My current line of thought is that processes are being created, but never released correctly. Our services are created from Castle, and registered from the web end as:
public static IWindsorContainer RegisterWcfService<TS, TI>(this IWindsorContainer container)
where TI : TS
where TS : class
{
container.Register(Component.For<TS>().ImplementedBy<TI>().Named(typeof(TI).Name)
.Interceptors<LoggingInterceptor>()
.Interceptors<ExceptionHandlerInterceptor>()
.LifeStyle.Transient
.AsWcfService(
GetServiceModel<TS, TI>()
));
return container;
}
As suggested in other threads, we are using
container.Kernel.ReleasePolicy = new NoTrackingReleasePolicy();
to ensure components should be correctly released. We are not explicitly disposing of any of our service references, although I believe the above should be enough. Does anyone have any recommendations or suggestions on where our leak might be coming from?
Unfortunately, manually managing disposal of WCF proxies is the most reliable way to ensure the release of memory for garbage collection and the release of network resources. This brief blog post explains some of the issues that cause WCF proxies to leak memory & network resources. Since you already configure the container to create transient proxy instances, you should wrap your service call logic in a pattern similar to the one shown in the article.
If this doesn't solve your issue, you many need to wade through a memory dump using WinDbg to find what the actual GC root holding a reference chain to the SlidingWindow instances.
PS: Don't be tempted to use a longer lived scope (request or perish the thought, a singleton) to try to solve this issue. The solution is proper disposal of the proxy instances. I found this out the hard way... ;-)
I have a WCF service which calls an STA Visual Basic 6.0 COM object. Everything works normally if only one client is using the service, but as soon as concurrent users start to call it, I'm in trouble and getting all kinds of random errors when calling one of the methods of the COM object.
At first I fixed this problem by adding support for the STAOperationBehavior attribute with the help of the article Calling an STA COM Object from a WCF Operation.
Well, it helped a lot and for some time everything seemed to work well, but now I started to get System.AccessViolationException errors on a particular server when more than one user is calling the service.
I've read that this is probably a thread problem, and I should use mutex or instancecontext in my web service.
What is the best practice for making sure that concurrent users can use an STA COM object in a WCF service without any problems?
If the object is not designed to be used simultaneously by multiple users, then you simply cannot allow multiple users to use it.
I am trying to write a running object table like WCF service (.NET 4.0) for providing access to some COM controls across processes. This service is accessed by both COM and .NET clients.
I chose WCF since it is recommended for inter-process communication and I also thought it would be good if I don't have to depend on ROT where I don't have much control over.
After solving several hiccups, I reached a road block. I don't know how to pass the COM control through the service and give it back to a client. The object never reaches the service. Though WCF is recommended for IPC, it does not provide out of the box support to pass COM objects. I also haven't found any solutions so far. May be WCF service is not the right approach to replace running object table. But I don't see a better way to do IPC.
Any suggestions on this?
A COM objref can't be passed around in a WCF message (well I guess you could create a MEOW interpreter on the receiver size and use CoMarshalInterThreadInterfaceInStream to pass the objref)
However, you could put the objects in the GIT and pass the GIT cookies around
But we can directly place COM object into the ROT by implementing IUNKNOWn interface
I have been trying to get up to speed on Named Pipes this week. The task I am trying to solve with them is that I have an existing windows service that is acting as a device driver that funnels data from an external device into a database. Now I have to modify this service and add an optional user front end (on the same machine, using a form of IPC) that can monitor the data as it passes between the device and the DB as well as send some commands back to the service.
My initial ideas for the IPC were either named pipes or memory mapped files. So far I have been working through the named pipe idea using WCF Tutorial Basic Interprocess Communication . My idea is to set the Windows service up with an additional thread that implements the WCF NamedPipe Service and use that as a conduit to the internals of my driver.
I have the sample code working, however I can not get my head around 2 issues that I am hoping that someone here can help me with:
In the tutorial the ServiceHost is instantiated with a typeof(StringReverser) rather than by referencing a concrete class. Thus there seems to be no mechanism for the Server to interact with the service itself (between the host.Open() and host.Close() lines). Is it possible to create a link between and pass information between the server and the class that actually implements the service? If so, how?
If I run a single instance of the server and then run multiple instance of the clients, it seems that each client gets a separate instance of the service class. I tried adding some state information to the class implementing the service and it was only retained within the instance of the named pipe. This is possibly related to the first question, but is there anyway to force the named pipes to use the same instance of the class that is implementing the service?
Finally, any thoughts on MMF vs Named Pipes?
Edit - About the solution
As per Tomasr's answer the solution lies in using the correct constructor in order to supply a concrete singleton class that implements the service (ServiceHost Constructor (Object, Uri[])). What I did not appreciate at the time was his reference to ensuring the service class was thread safe. Naively just changing the constructor caused a crash in the server, and that ultimately lead me down the path of understanding InstanceContextMode from this blog entry Instancecontextmode And Concurrencymode. Setting the correct context nicely finished off the solution.
For (1) and (2) the answer is simple: You can ask WCF to use a singleton instance of your service to handle all requests. Mostly all you need to do is use the alternate ServiceHost constructor that takes an Object instance instead of a type.
Notice, however, that you'll be responsible for making your service class thread safe.
As for 3, it really depends a lot on what you need to do, your performance needs, how many clients you expect at the same time, the amount of data you'll be moving and for how long it needs to be available, etc.
I have a WCF server that is a library assembly. (I am writing it so I can mock the level below it) It is called var a client helper class that is in a different assembly. As the data that is transferred is complex and the server has to send call-backs to the clients I wish to test the WCF code in isolation.
(I am only interested in the TCP channel or NamePipe channel)
I do not wish to mock WCF, as the risk I am trying to control is my usage of WCF.
It there a easy way to
Load my WCF server into a different app domain
(I could load the WCF server into the main app domain, but then I it harder to prove that the objects were serialized correctly rather than just pointer moved about.)
Setup all the WCF config so the client class can call it (most likely named pipes or TCP)
And use it in some nunit test
I rather not have my unit tests depending on config file.
I expect (hope) that there are some util classes for setting up WCF unit test that I can just pass the type of my server class to and will give me back a client factory that connects to the server.
Am I going about this the wrong way, e.g there a better way of testing my communication layer and usage of WCF?
It is by far the easiest approach if you spin up the service in-proc, because then you don't need to write a lot of complex synchronization code to determine when the service is running and when it isn't.
Don't worry about pointers being passed around - they won't (unless you choose the new in-proc binding in WCF 4). It's the binding that determines how and if objects are serialized. Named pipes are excellent for this purpose.
I always spin up a new ServiceHost in each test case inside a using statement, which effectively guarantees that the host is running before calls are being made to it, and that it is properly closed after each test. This last part is important because it ensures test independence.
You may also want to look at a series of blog posts I wrote about a very similar subject.
You can use SOA Cleaner for testing your WCF. Take a look at http://xyrow.com
no installation is needed. It's not unit testing, but it can be very helpful (you can have it run on your build, as it supports command line too).