Handling Thread Exceptions in WCF - wcf

Our WCF services occaisionally spawn a worker thread to handle something that the client doesn't care about. The worker threads do not report any status back to the client. In fact, the service has probably already returned results to the client by the time the thread finishes.
One of these background threads recently caused an exception. The exception went unhandled, so IIS crashed.
I can fix this particular exception, but in the future, someone may add some code that causes another unexpected exception. I want to prevent this from crashing IIS in the future.
I know System.Windows.Forms apps can handle thread exceptions by implementing Application.ThreadException. Is there something similar I can do from a WCF service? Or if Application.ThreadException is the way to go, how would I hook it up from a WCF service?
The MSDN documentation for AppDomain.UnhandledException says it does not prevent crashing. Docs for ServiceModel.AsynchronousThreadExceptionHandler suggest it is only for WCF threads.
At a minimum, I'd like to grab a stack trace from the exception before crashing, but avoid future crashes completely would be ideal.
Again, let me stress this is not an exception I want to return as a WCF fault to a client.

Since you don't know what caused the exception, the only sensible thing to do is crash. You have no idea what state the service is in, and you could make things worse by continuing.
Remember that IIS will restart the service for you, clean, and presumably working.

If you're spawning threads, you should always make sure they have exception guards. The AppDomain handling for unhandled exceptions only provides a way to log and trace the error, but it won't stop the host from crashing.

You could take a look at implementing IErrorHandler with a Dispatch Behavior:
http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.ierrorhandler.aspx

Related

Recovery on Failure for a Windows Service Application

I am having trouble getting the feature recovery on failure to work for my Windows Service Application. I set in up to restart the application on first failure. Then to test in I use this line of code
System.Environment.Exit(-1)
This causes the application to end okay but it doesn't restart.
It is reasonable to suppose that a service process exiting without setting the service status to stopped would constitute a failure. However, that isn't the case. (Perhaps for backwards compatibility; there might be too many third-party services that such a change would break.)
However, if the process exits as the result of an unhandled exception, that is considered a service failure and triggers the recovery options. So if you want to cause the service to fail, raise an exception (and don't catch it).

WCF Service Not Reading Messages in Queue

I have a WCF service that reads from a message queue. I noticed with our latest deployment that there is a message sitting in the queue that has not been read. The WCF service is up and running and it is correctly establishing a connection to the queue (or I would receive and error).
We made some changes to our code recently and we are wondering if perhaps that is related. It seems odd to us that the service would be running and yet the message not read. At a minimum, I would expect WCF to throw some sort of error if there was a malformed message in the queue.
I looked at the properties of the message and it says there have been zero moves, so I don't think it is being sent to a retry sub-queue. It is just sitting there and the service won't read it.
Is there a circumstance where WCF would ignore a message in the queue? How does WCF handle malformed messages?
Sorry if this isn't a lot of information to go on. At this point I am just trying to understand what is preventing the message from being processed.
This situation seemed just too odd. It didn't make sense that WCF would do nothing at all.
I eventually decided to simply try restarting the MSMQ service on the server. Once I did that, my service immediately picked up the messages and everything started working again.
I have no idea if this had something to do with a Windows Update or some other server change. I am glad it was this easy to fix - it will be the first thing I try in the future.

Self-hosted WCF service inaccessible in IIS+AppFabric

For a few weeks now I've been having a really weird problem. I have a couple of services which work just fine when self-hosted in a command line app. However in IIS+AppFabric I cannot access one of the services - I get TimeoutException and am pretty sure that the call doesn't even make it to the service (all services have an aspect to log all calls before doing anything). Note that both services are configured identically with regards to bindings and behaviors by code. I tried many things like putting them on different app pools, disabling some of the transports... And what is really strange that if both services are in one app pool - one of the services works but if I put them on separate threads - the other service times-out. It really drives me nuts...
Also I see pretty often events in the system event log: "A process serving application pool 'Authorization Management' suffered a fatal communication error with the Windows Process Activation Service. The process id was '11852'. The data field contains the error number." The error number is 0x80070218. After the event the service host initializes without problems (I can see my own info log messages) however the service is unreachable.
Does this ring a bell to anyone?
Thanks!
It turned out that I had a bug in the initialization of the services' hosts. I was trying something, and when I removed the try code, apparently I didn't delete the first line which was locking some resource.
Anyway, it is a good lesson. Nevertheless, if your services do not work, your initialization might be buggy...
Sorry about the noice.

End a WCF Session from the Server?

This may be a shot in the dark (I don't know much about the internals of WCF), but here goes...
I'm currently working with a legacy application at a client site and we're experiencing a persistent issue with a WCF service. The application is using the Microsoft Sync Framework 2.0 and syncing through the aforementioned service. The server-side implementation of the service has a lot of custom code in various states of "a mess."
Anyway, we're seeing an error on the client application most of the time and the pattern we're narrowing down centers around different users using the application on the same machine hitting the same service. It seems that the service and the client are getting out of sync in some way on an authentication level.
The error is discussed in an article here, and we're currently investigating the approach of switching from message layer security to transport layer security, which will hopefully solve the problem. However, we may be able to solve it in a less invasive manner if this question makes sense.
In the linked article, one of the suggestions was to forcibly terminate the connection if the specific exception is caught, try again, and if it fails again it wasn't because of this particular theory. Sounds good, and easy to implement. However, I find myself unable to say with confidence if the connection is being properly terminated.
The service operates through a custom interface, which is implemented on the server-side. The only thing that interface can do to end the connection is call EndSession() on the proxy itself, which calls EndSession() on the server which is a custom method.
So...
From a WCF service method, is there a way to properly and gracefully terminate the connection with the client in a way the client will like?
That is, in this custom EndSession() is there some last step I can take to cause the server to completely forget that this connection was open? Because it seems like when another user on the same machine tries to hit the service within the application, that's when it fails with the error in the linked article.
The idea is that, at the client side of things, code which calls EndSession() is followed by nulling out the proxy object, then a factory method is called to supply another one the next time it's needed. So I wonder if something additional needs to happen on the server side (and does by default in WCF were it not for all this custom implementation code) to terminate the connection on that end?
Like I said, a shot in the dark. But maybe in answers/discussions here I can at least further diagnose the problem, so any help is much appreciated. Thanks.
Unfortunately there are only really three ways in which a session can terminated
The client closes the proxy
The service's receiveTimeout is exceeded
before the client sends another
request
the service throws a
non-fault exception which will fault
the channel and so terminate the
session
if you don't want the client involved then you only have 2 and 3 neither of which end well for the client - they will get an exception in both situation on the next attempt to talk to the service.
You could use Duplex messaging and get the service to notify the client that its requires session termination - the client then gets an opportunity to close down the proxy gracefully but this is a cooperative strategy

WCF Service hangs and clients receive a ServiceModel.CommunicationException

My application has 50 service endpoints (such as /mysite/myService.svc). It's hosted in IIS. Intermittently (once every two or three days) a service stops responding. It's never the same service that hangs. While a service is hung, some of the other services work fine and some other are also hung.
All clients (from different computers) get this error:
ServiceModel.CommunicationException
Message: An error occurred while receiving the HTTP response to
https://server/mysite/myservice1.svc.
This could be due to the service endpoint binding not using the HTTP
protocol. This could also be due to an HTTP request context being
aborted by the server (possibly due to the service shutting down).
See server logs for more details.
No exceptions are raised by the server when the client attempts to call the service that is hung. All I have is that error on the client side.
I have to manually recycle the application pool to fix the problem.
Do you know what could be the cause? How can I investigate this issue? I'm willing to take a memory dump of the worker process when a service is hung but I would not know what to search for in the dump.
Update (Aug 13 2009): I have almost ruled out the idea that the server runs out of connections (see comment in Shiraz Bhaiji's answer). I might have a new lead: I log all server-side exceptions in a log file. So in theory, when this occurs on the client, no exceptions are raised on the server; otherwise I'd have proof of that in my logs. But what if an error does occur on the server but is happening at a low level where exceptions are not routed to my exception handling code? I have posted this question about scenarios where low level exceptions cannot be handled. I'll keep you informed of the progress of my investigation.
Sounds like you are running out of connections.
By default WCF has a timeout and therefore holds a connection open for 10 mins.
When you recycle the app pool all connections are closed, and therefore things work again.
To fix it check your code to make sure that you close connections / dispose of proxies.
To resolve this, we set establishSecurityContext to False on the binding.
I have not come across this particular issue but would suggest to turn on tracing/message logging for the WCF service in the config for the service and/or the client app (if you have control over that). I've done this in the last few days for a service that I needed to troubleshoot.
The MSDN link here is a good starting point.
Also see the table in this post for the varying levels of trace detail you can configure. There are several levels which can go from exception only logging to full message details. It is quite quick to set this up in the app.config file.
To parse the log file output use the SvcTraceViewer.exe that comes with the Windows SDK, which if you have it installed should be located in this folder: C:\Program Files\Microsoft SDKs\Windows\v6.0\Bin