我已經在C#中編寫了Excel的包裝器,以便允許在批處理過程(在JobScheduler下)中運行Excel工作簿。我的問題是這樣的......運行代碼時退出Interop受控Excel
如果代碼運行時間過長或需要通過作業調度程序終止,則包裝程序需要處理此終止事件。爲此,我添加了
SetConsoleCtrlHandler(new HandlerRoutine(ConsoleCtrlCheck), true);
代碼。在ConsoleCtrlCheck方法中,我調用一個通用的退出例程(用於正常或終止環境)。這種路由做以下按MS建議..
關閉並釋放工作簿
關閉並釋放Excel中
垃圾收集
,然後用Excel的方法被調用的返回碼退出(中入口點)。 這個效果很好。
但是,如果VBA代碼仍在運行,則Interop對象不會響應工作簿關閉或應用程序退出調用。這可能是因爲一切都變得緩慢,或者因爲模態對話已經發出。 爲了解決這個我添加了以下這個普通程序開始...
- 創建新的線程來運行KillExcel方法
- KillExcel法睡在指定時間內(所以正常退出代碼有一個工作的機會),然後殺死進程
- 如果正常的代碼工作它調用中止的線程上
private static void Cleanup()
{
// Give this X seconds then terminate
mKillThread = new Thread(KillExcel);
mKillThread.IsBackground = false;
mKillThread.Start();
...
// close the workbooks and excel application
// Marshal.FinalReleaseComObject etc
GC.Collect();
GC.WaitForPendingFinalizers();
// Not sure if necessary but makes sure Process gone
try
{
Process p = Process.GetProcessById(mExcelPid);
p.WaitForExit();
}
catch(ArgumentException)
{}
mKillThread.Abort();
}
private static void KillExcel()
{
Thread.Sleep(Settings.Default.KillWaitMilliSeconds);
if (mLog.IsInfoEnabled)
mLog.Info(string.Format("Waited {0} seconds, killing Excel process [{1}]",Settings.Default.KillWaitMilliSeconds/1000, mExcelPid));
try
{
Process p = Process.GetProcessById(mExcelPid);
if (!p.HasExited)
p.Kill();
}
catch(ArgumentException)
{
}
}
我的問題是,有沒有要去一個更好的辦法回合或者這是爲了確保在作業終止事件中刪除excel進程的方式?