The answer to your question has been covered here i think:
How to properly clean up excel interop objects in c
i cant see from your code sample, but basically, always assign your excel objects to local variables, never going 'two dots down', like this:
//FAIL
Workbook wkBook = xlApp.Workbooks.Open(@"C:\mybook.xls");
instead ref each obj individually:
//WIN
Worksheets sheets = xlApp.Worksheets;
Worksheet sheet = sheets.Open(@"C:\mybook.xls");
...
Marshal.ReleaseComObject(sheets);
Marshal.ReleaseComObject(sheet);
.NET creates a wrapper for the COM object that is invisible to you and is not released until the GC weaves its magic.
Until I discovered this, I was running the hacky code below in an ASP.NET application each time i created a new workbook that that checks the age of the excel.exe process and kills any that are over a minute old:
//force kill any excel processes over one minute old.
try
{
Process[] procs = Process.GetProcessesByName("EXCEL");
foreach (Process p in procs)
{
if (p.StartTime.AddMinutes(1) < DateTime.Now)
{
p.Kill();
}
}
}
catch (Exception)
{}