I apologize in advance for the long post...
I'm looking for some advice on how to deal with a problem that I am encountering with some software that I wrote for a client. In short, the client has a third-party document management system that stores their shipping orders, invoices, etc. When new documents are created, the client needs copies saved and printed in order to be shipped with the merchandise that they sell. The third-party software manufacturer makes an SDK with a .NET DLL that allows C# and VB.NET programs to query and save documents out. So I wrote them a program that uses this DLL to periodically scan the system, and when it finds new documents, my program will save them to a temp directory and print them. Everything works well, except that the SDK wasn't very well made, so whenever the method to save a document is called, a bunch of stuff gets loaded into RAM that the third-party SDK doesn't get rid of (i.e. it doesn't manage memory very well). Sometimes the client will run large batches and this accumulation of RAM will slow down their system, and has caused Out of Memory exceptions a couple times. I wrote some sample code to simulate the problem. It does take a little imagination, but it'll give you a good idea of the problem that I have to overcome. The first code sample simulates a class in the third-party's DLL.
The "DLL" Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
using System.Threading.Tasks;
namespace DisposeSample
{
public class OtherGuysDllClass
{
/*
This is intended to simulate the SDK class library where the memory
leak occurs. It ships with the third-party software that it integrates with, and
I can't change it. Pretend this is a .dll that I referenced in my project.
*/
public OtherGuysDllClass()
{
/*
I wrote this to simulate a process that would build up in memory over time. The SDK doesn't
do this per se, but something similar that causes junk to accumulate in RAM over time.
*/
StreamWriter sw = new StreamWriter(Environment.CurrentDirectory + "\\output.txt");
sw.WriteLine(DateTime.Now.ToString());
sw.Close();
}
}
}
You can see that the code in the above class contains a StreamWriter object that was not properly disposed of, so it will cause some junk to be left in memory. Again, the DLL doesn't do this exactly, but something that will cause a memory problem like the sample above.
I also wrote a WinForms app with a timer control to periodically create a new object from the above class that simulates the program that I wrote for the client.
My program:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace DisposeSample
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
timer1.Interval = 500;
timer1.Enabled = true;
}
/*
Timer1 Tick Event Handler
(This Timer Control was dragged and dropped onto the form in the designer).
*/
private void timer1_Tick(object sender, EventArgs e)
{
OtherGuysDllClass dllObj = new OtherGuysDllClass();
dllObj = null;
/*
Is there any way to make the program wipe the ddlObj and everything it created from
memory? I tried calling GC.Collect(), but it didn't help much.
*/
}
}
}
So imagine that you were given a DLL that contains a class like the top one, and you had a program running round-the-clock that periodically creates instances of the class. How would you get around the problem of the gradual accumulation of objects in memory. Any suggestions/advise would be appreciated.
Thanks!