views:

1482

answers:

4

This is in C#, Visual Studio 2008, crystal reports that came with VS2008

I've got a crystal report viewer form that resides in a DLL. The DLL is responsible for loading the crystal report (based on report filename), and displaying the report on the form.

When I'm done with the crystal report, i call dispose on the loaded reportdocument object. However, the database connection remains.

Crystal seems to detect that there are other connections (from my main application) to the same database, and keeps its connection open. The crystal connection is closed when the main applications database connection is closed.

Is there any way to force crystal to close its connection, with out closing the main applications database connection?

A: 

I'm not too familiar with Crystal Reports, but there are many objects which have a useless Dispose() method due to an inheritance chain that includes the IDisposable interface. If you are not seeing any performance problems on the server, then don't worry about it. The GC will take care of the connections on the clients when it is ready. You shouldn't try to be smarter than the GC, you will only give yourself more headaches.

And, always call Dispose() (or using{}) when it is available.

Ariel
This is really about the database connection. The main application has functionality to restore and backup the database. The crystal db connection prevents this. I've had a scurry around on google, and disposing the report closes the connection, but only if crystal is the only thing connected.
I'm assuming that you are using MSSQL, correct? Why not use the built in backup/restore from there?
Ariel
because the product is designed to be used by non-technical people. Having two menu items that say backup/restore is alot easier to understand then go into sql management studio, log in as a user who has those privs etc.
I would be careful when using the work "always". You start by saying many objects have a useless Dispose method, would be make sense to always use it or using then?
Chris Nicola
+1  A: 

How are you connecting to the database, by creating your own connection at runtime via setting the authentication or are you letting Crystal do the connection via the stored connection in the report? If you are doing your own connection in any way, shape, or form, you have to manually close the connection and call the dispose before disposing the report.

It is quite possible this is a memory leak. I have experienced these before. There is also a memory leak issue with Crystal Reports and is talked about on their forum quite a bit but no fix was issued when I was using it a few years ago. I ditched Crystal for other options.

TheCodeMonk
A: 

I had the same problem, except I'm using Sybase. A little while ago I was posting the code I wrote to dispose of the connection (and that didn't work) when I saw an error! I fixed the error, and, cross my fingers, now it seems to work. I've opened almost 100 reports where I couldn't open 10 before. If you try this, please let me know if it works for you.

Here is what I'm doing right before I close the window that contains the Crystal Reports viewer:

var rd = (ReportDocument)crystalReportViewer1.ReportSource;
foreach (Table table in rd.Database.Tables)
   table.Dispose();
rd.Database.Dispose();
rd.Close();
rd.Dispose();
GC.Collect();

Mark

Mark
A: 

Marks code seems to somewhat relieve the situation although it is a bit backwards, should be something like:

ReportDocument rd = (ReportDocument) viewer.ReportSource;
foreach (Table table in rd.Database.Tables)
    table.Dispose();
viewer.ReportSource = null;
rd.Database.Dispose();
rd.Close();
rd.Dispose();
rd = (ReportDocument) viewer.ReportSource;  
GC.Collect();

This didn't completely plug the leak for me but certainly helped.

PeteT