25 Jan
2010

Calls to ReportExecutionService.Render() Hang

Given: One Windows Service, written in C#, using SQL Reporting Services via the SSRS web services.  MyApp.Service waits for work requests to come in, and when it finds them it uses SSRS to generate some PDFs (among a bunch of other stuff).  The Windows Service code is in one project, “myapp.service,” and the code that does all the work is in a shared project, “myapp.core.”. 

Problem: The raw bytes of the PDF are returned from SSRS by using the class Microsoft.SqlServer.ReportingServices2005.Execution.ReportExecutionService, via the Render() method.  This code works just fine in Dev, Test, and Stage environments – but in Production, without fail, this Render() method hangs and will never return back to the service process.

The Fix:  This functionality is a small bit in a much larger application, and even the PDF generation is a smallish piece of some larger responsibilities for the service.  So first, I want to isolate the behavior, and then duplicate it. 

I wrote a test windows service consisting of one project, that does one thing: when a timer fires, a hardcoded request to the production Reporting Services is made to get a PDF bytestream.  This service does what is expected in Dev and Stage, but when I tried to install it on Production:

An exception occurred while trying to find the installers in the C:\webreader\webreader.svc.exe assembly.
System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
Aborting installation for C:\webreader\webreader.svc.exe.

Can’t load a type?!  So I copy Microsoft.ReportViewer.Common.dll and Microsoft.ReportViewer.WebForms.dll into the program directory, and my test service installs and works perfectly.  Copying the same files into the production service’s directory also fixes the problem.

 

So, if your Reporting Services ASMX calls are hanging, try changing your references over to “Copy Local” and see what happens…

 

Why this is weird: If those DLLs were missing or corrupt, then why did the original App code load and run (and hang)?  I thought perhaps the wrong version was referenced in the GAC, but no there were NO Microsoft.ReportViewer.*.dll’s registered.  The service installer caught the missing types when the references were all in one assembly, but didn’t have any problems when the references were spread into a 2nd assembly. 

Just when I think “hey, maybe I’m getting a hang of this .NET stuff” a problem like this happens…

3 thoughts on “Calls to ReportExecutionService.Render() Hang

  1. @Robert
    Yeah, how come I wasn’t getting a TypeLoadException? Or if some assembly was being loaded, where was it coming from if it wasn’t in the GAC and wasn’t local? (This is running on a 32 bit virtual, so theres no 64 bit weirdness there…) Is there something about Windows Services that eat loading exceptions? Why did the call to the phantom object hang instead of throw an exception, terminate the service, or something else more reasonable?

  2. My *guess* (and a totally wild one at that) is that you didn’t get an exception on process start/running because the missing assembly wasn’t noticed until it was needed (potential external references are not a problem until they are needed).

    I suspect the deadlock is because one thread made the async call which started another thread which ended up dying while initializing (i.e. while the threadstart method was being JIT’ed). This means that it never really started and therefore never sent any events (such as a failure event) to unlock the calling thread (which apparently did not have any sort of timeout).

    But that’s all speculation 🙂

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.