2
我有這樣一段代碼用於從Excel單元讀取:Excel對象不獲取設置有時
public T GetValue<T>(string testsheet, string range)
{
Application excelApplication = null;
Workbooks workBooks = null;
Workbook activeWorkBook = null;
Worksheet activeWorkSheet = null;
try
{
excelApplication = new Application();
workBooks = excelApplication.Workbooks;
activeWorkBook = workBooks.Open(workBook);
activeWorkSheet = activeWorkBook.ActiveSheet;
var cells = activeWorkSheet.get_Range(range);
return cells.Value2;
}
catch (Exception theError)
{
Console.WriteLine(theError.Message);
throw theError;
}
finally
{
ReleaseComObject(activeWorkSheet);
ReleaseComObject(activeWorkBook);
ReleaseComObject(workBooks);
ReleaseComObject(excelApplication);
}
}
另外我有這設定值對小區的設定值以下方法:
public void SetValue<T>(string testsheet, string range, T value)
{
Application excelApplication = null;
Workbooks workBooks = null;
Workbook activeWorkBook = null;
Worksheet activeWorkSheet = null;
try
{
excelApplication = new Application();
workBooks = excelApplication.Workbooks;
activeWorkBook = workBooks.Open(workBook);
activeWorkSheet = activeWorkBook.ActiveSheet;
var cells = activeWorkSheet.get_Range(range);
cells.Value2 = value;
activeWorkBook.Save();
}
catch (Exception theError)
{
Console.WriteLine(theError.Message);
throw theError;
}
finally
{
if (activeWorkBook != null)
activeWorkBook.Close();
ReleaseComObject(excelApplication);
ReleaseComObject(workBooks);
ReleaseComObject(activeWorkBook);
ReleaseComObject(activeWorkSheet);
}
}
這裏是我的ReleaseComObject的:
private static void ReleaseComObject<T>(T comObject) where T : class
{
if (comObject != null)
Marshal.ReleaseComObject(comObject);
}
我寫了一個測試,以確保Excel對象是properl ý設置如下:
[Test]
public void Should_dispose_excel_objects_created_after_io_operation()
{
var expected = Process.GetProcesses().Count(process => process.ProcessName.ToLower() == "excel");
var automationClient = new ExcelAutomation.ExcelAutomationClient(ExcelSheet);
automationClient.SetValue("Sheet1", "A1", 1200);
automationClient.GetValue<double>("Sheet1", "A1");
var actual = Process.GetProcesses().Count(process => process.ProcessName.ToLower() == "excel");
actual.Should().Be(expected, "Excel workbook is not disposed properly. There are still excel processess in memory");
}
此測試passess如果我只調用setValue方法,但是在調用的GetValue它失敗。但是我可以在taskmanager中看不到Excel.exe。任何想法爲什麼發生這種情況?我的GetValue函數有問題嗎?
我相信'get_Range'返回一個COM對象,所以你應該釋放,太。雖然,你在你的兩種方法中調用它。 – BACON 2012-02-08 00:20:52
它與處置沒有任何關係。您正在編寫C代碼,手動管理內存。產生不可避免的錯誤,「泄漏」內存。您沒有爲* cells *對象引用調用ReleaseComObject()。只是不要寫這樣的代碼,沒有意義。垃圾收集器已經知道如何做到這一點。如果你想由於某種原因而急於調用GC.Collect()。只要你有一個很好的理由。 – 2012-02-08 00:30:58
如果你比較兩種方法,我做的事情幾乎是一樣的。如果我不調用ReleaseComObject,則Excel實例在內存中不存在。只有在呼籲它消失之後。即使在這種情況下,它也會消失,但是測試沒有通過。 – Mike 2012-02-08 00:35:47